詳解MySQL分割槽表
前言:
分割槽是一種表的設計模式,通俗地講表分割槽是將一大表,根據條件分割成若干個小表。但是對於應用程式來講,分割槽的表和沒有分割槽的表是一樣的。換句話來講,分割槽對於應用是透明的,只是資料庫對於資料的重新整理。本篇文章給大家帶來的內容是關於MySQL中分割槽表的介紹及使用場景,有需要的朋友可以參考一下,希望對你有所幫助。
1.分割槽的目的及分割槽型別
MySQL在建立表的時候可以通過使用PARTITION BY子句定義每個分割槽存放的資料。在執行查詢的時候,優化器根據分割槽定義過濾那些沒有我們需要的資料的分割槽,這樣查詢就可以無需掃描所有分割槽,只需要查詢包含需要資料的分割槽即可。
分割槽的另一個目的是將資料按照一個較粗的粒度分別存放在不同的表中。這樣做可以將相關的資料存放在一起,另外,當我們想要一次批量刪除整個分割槽的資料也會變得很方便。
下面簡單介紹下四種常見的分割槽型別:
- RANGE分割槽:最為常用,基於屬於一個給定連續區間的列值,把多行分配給分割槽。最常見的是基於時間欄位。
- LIST分割槽:LIST分割槽和RANGE分割槽類似,區別在於LIST是列舉值列表的集合,RANGE是連續的區間值的集合。
- HASH分割槽:基於使用者定義的表示式的返回值來進行選擇的分割槽,該表示式使用將要插入到表中的這些行的列值進行計算。這個函式可以包含MySQL中有效的、產生非負整數值的任何表示式。
- KEY分割槽:類似於按HASH分割槽,區別在於KEY分割槽只支援計算一列或多列,且MySQL伺服器提供其自身的雜湊函式。必須有一列或多列包含整數值。
上述四種分割槽型別中,RANGE分割槽 即範圍分割槽是最常用的。RANGE分割槽的特點是多個分割槽的範圍要連續,但是不能重疊,預設情況下使用VALUES LESS THAN屬性,即每個分割槽不包括指定的那個值。
2.分割槽操作示例
本節內容以RANGE分割槽為例,介紹下分割槽表相關的操作。
# 建立分割槽表 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,-> `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分割槽相關內容,如果想使用分割槽表的話,建議提早做好規劃,在初始化的時候即建立分割槽表並制定維護計劃,使用得當還是比較方便的,特別是有歷史資料歸檔需求的表,使用分割槽表會使歸檔更方便。當然,關於分割槽表的內容還有很多,有興趣的同學可以找找官方文件,官方文件中有大量示例。
以上就是詳解MySQL分割槽表的詳細內容,更多關於MySQL分割槽表的資料請關注我們其它相關文章!