MySQL分區表最佳實踐

前言:html

分區是一種表的設計模式,通俗地講表分區是將一大表,根據條件分割成若干個小表。可是對於應用程序來說,分區的表和沒有分區的表是同樣的。換句話來說,分區對於應用是透明的,只是數據庫對於數據的從新整理。本篇文章給你們帶來的內容是關於MySQL中分區表的介紹及使用場景,有須要的朋友能夠參考一下,但願對你有所幫助。mysql

1.分區的目的及分區類型

MySQL在建立表的時候能夠經過使用PARTITION BY子句定義每一個分區存放的數據。在執行查詢的時候,優化器根據分區定義過濾那些沒有咱們須要的數據的分區,這樣查詢就能夠無需掃描全部分區,只須要查找包含須要數據的分區便可。sql

分區的另外一個目的是將數據按照一個較粗的粒度分別存放在不一樣的表中。這樣作能夠將相關的數據存放在一塊兒,另外,當咱們想要一次批量刪除整個分區的數據也會變得很方便。數據庫

下面簡單介紹下四種常見的分區類型:設計模式

  • RANGE分區:最爲經常使用,基於屬於一個給定連續區間的列值,把多行分配給分區。最多見的是基於時間字段。
  • LIST分區:LIST分區和RANGE分區相似,區別在於LIST是枚舉值列表的集合,RANGE是連續的區間值的集合。
  • HASH分區:基於用戶定義的表達式的返回值來進行選擇的分區,該表達式使用將要插入到表中的這些行的列值進行計算。這個函數能夠包含MySQL中有效的、產生非負整數值的任何表達式。
  • KEY分區:相似於按HASH分區,區別在於KEY分區只支持計算一列或多列,且MySQL服務器提供其自身的哈希函數。必須有一列或多列包含整數值。

上述四種分區類型中,RANGE分區即範圍分區是最經常使用的。RANGE分區的特色是多個分區的範圍要連續,可是不能重疊,默認狀況下使用VALUES LESS THAN屬性,即每一個分區不包括指定的那個值。服務器

2.分區操做示例

本節內容以RANGE分區爲例,介紹下分區表相關的操做。less

# 建立分區表
mysql> CREATE TABLE `tr` (
    ->   `id` INT, 
    ->   `name` VARCHAR(50), 
    ->   `purchased` DATE
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    -> PARTITION BY RANGE( YEAR(purchased) ) (
    -> PARTITION p0 VALUES LESS THAN (1990),
    -> PARTITION p1 VALUES LESS THAN (1995),
    -> PARTITION p2 VALUES LESS THAN (2000),
    -> PARTITION p3 VALUES LESS THAN (2005),
    -> PARTITION p4 VALUES LESS THAN (2010),
    -> PARTITION p5 VALUES LESS THAN (2015)
    -> );
Query OK, 0 rows affected (0.28 sec)

# 插入數據
mysql> INSERT INTO `tr` VALUES
    ->     (1, 'desk organiser', '2003-10-15'),
    ->     (2, 'alarm clock', '1997-11-05'),
    ->     (3, 'chair', '2009-03-10'),
    ->     (4, 'bookcase', '1989-01-10'),
    ->     (5, 'exercise bike', '2014-05-09'),
    ->     (6, 'sofa', '1987-06-05'),
    ->     (7, 'espresso maker', '2011-11-22'),
    ->     (8, 'aquarium', '1992-08-04'),
    ->     (9, 'study desk', '2006-09-16'),
    ->     (10, 'lava lamp', '1998-12-25');
Query OK, 10 rows affected (0.03 sec)
Records: 10  Duplicates: 0  Warnings: 0
複製代碼

建立後能夠看到,每一個分區都會對應1個ibd文件。上面建立語句仍是很好理解的,在此分區表中,經過YEAR函數取出DATE日期中的年份並轉化爲整型,年份小於1990的存儲在分區p0中,小於1995的存儲在分區p1中,以此類推。請注意,每一個分區的定義順序是從最低到最高。爲了防止插入的數據因找不到相應分區而報錯,咱們應該及時建立新的分區。下面繼續展現關於分區維護的其餘操做。函數

# 查看某個分區的數據
mysql> SELECT * FROM tr PARTITION (p2);
+------+-------------+------------+
| id   | name        | purchased  |
+------+-------------+------------+
|    2 | alarm clock | 1997-11-05 |
|   10 | lava lamp   | 1998-12-25 |
+------+-------------+------------+
2 rows in set (0.00 sec)

# 增長分區
mysql> alter table tr add partition(
    -> PARTITION p6 VALUES LESS THAN (2020)
    -> );
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0

# 拆分分區
mysql> alter table tr reorganize partition p5 into(
    ->   partition s0 values less than(2012),
    ->   partition s1 values less than(2015)
    -> );
Query OK, 0 rows affected (0.26 sec)
Records: 0  Duplicates: 0  Warnings: 0

# 合併分區
mysql> alter table tr reorganize partition s0,s1 into ( 
    ->     partition p5 values less than (2015) 
    -> );
Query OK, 0 rows affected (0.12 sec)
Records: 0  Duplicates: 0  Warnings: 0

# 清空某分區的數據
mysql> alter table tr truncate partition p0;
Query OK, 0 rows affected (0.11 sec)

# 刪除分區
mysql> alter table tr drop partition p1;
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0

# 交換分區
# 先建立與分區表一樣結構的交換表
mysql> CREATE TABLE `tr_archive` (
    ->   `id` INT, 
    ->   `name` VARCHAR(50), 
    ->   `purchased` DATE
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.28 sec)
# 執行exchange交換分區 
mysql> alter table tr exchange PARTITION p2 with table tr_archive;
Query OK, 0 rows affected (0.13 sec)    
複製代碼

3.分區注意事項及適用場景

其實分區表的使用有不少限制和須要注意的事項,參考官方文檔,簡要總結幾點以下:性能

  • 分區字段必須是整數類型或解析爲整數的表達式。
  • 分區字段建議設置爲NOT NULL,若某行數據分區字段爲null,在RANGE分區中,該行數據會劃分到最小的分區裏。
  • MySQL分區中若是存在主鍵或惟一鍵,則分區列必須包含在其中。
  • Innodb分區表不支持外鍵。
  • 更改sql_mode模式可能影響分區表的表現。
  • 分區表不影響自增列。

從上面的介紹中能夠看出,分區表適用於一些日誌記錄表。這類表的特色是數據量大、而且有冷熱數據區分,能夠按照時間維度來進行數據歸檔。這類表是比較適合使用分區表的,由於分區表能夠對單獨的分區進行維護,對於數據歸檔更方便。學習

4.分區表爲何不經常使用

在咱們項目開發中,分區表實際上是不多用的,下面簡單說明下幾點緣由:

  • 分區字段的選擇有限制。
  • 若查詢不走分區鍵,則可能會掃描全部分區,效率不會提高。
  • 若數據分佈不均,分區大小差異較大,可能性能提高也有限。
  • 普通表改形成分區表比較繁瑣。
  • 須要持續對分區進行維護,好比到了6月份前就要新增6月份的分區。
  • 增長學習成本,存在未知風險。

總結:

本文較爲詳細的介紹了MySQL分區相關內容,若是想使用分區表的話,建議提前作好規劃,在初始化的時候即建立分區表並制定維護計劃,使用得當仍是比較方便的,特別是有歷史數據歸檔需求的表,使用分區表會使歸檔更方便。固然,關於分區表的內容還有不少,有興趣的同窗能夠找找官方文檔,官方文檔中有大量示例。

參考:

wx_blog.png
相關文章
相關標籤/搜索