动态

详情 返回 返回

MYSQL分區 - 动态 详情

一:概念

MySQL從5.1版本開始支持分區的功能。分區是指根據一定的規則,數據庫把一個表分解成多個更小的、更容易管理的部分。就訪問數據庫的應用而言,邏輯上只有一個表或一個索引,但是實際上這個表可能由數10個物理分區對象組成,每個分區都是一個獨立的對象,可以獨自處理,可以作為表的一部分進行處理。分區對應用來説是完全透明的,不影響應用的業務邏輯。

二:分區優點

  1. 性能提升: 分區可以提高查詢性能,特別是當查詢只涉及到某個分區的數據時,數據庫可以僅掃描相關分區,而不是整個表。這樣可以減少IO操作,提高查詢速度。
  2. 數據維護簡化: 分區使得數據的維護更加靈活和簡便。可以更容易地執行針對某個特定分區的數據備份、恢復、重新構建索引等操作,而不會影響整個表的數據。
  3. 空間管理: 分區可以幫助更有效地管理存儲空間。例如,可以將歷史數據移動到不同的分區,以便更容易地進行歸檔或刪除。這有助於降低整個數據庫的存儲成本。
  4. 更好的併發控制: 在某些情況下,使用分區可以提高併發性,因為不同的分區可以並行處理不同的查詢請求。
  5. 更容易維護大型表: 對於非常大的表,分區可以幫助提高查詢性能和維護效率,使其更容易處理和管理。
  6. 維護成本低。如果一個成熟的業務遇到瓶頸後引入表分區技術,與分表比起來代碼維護量小,基本不用改動,且不需額外創建子表。

三:分區侷限性

  1. 必須使用分區字段才行,不然分區查詢就會失敗。走所有分區,這樣反而導致查詢變慢,性能不升反降
  2. 分區鍵選擇選擇不當後,可能會導致不均勻的數據分佈,進而影響性能
  3. 分區的實施和管理可能會增加數據庫的複雜性。在設計和維護分區方案時,需要考慮額外的管理和維護工作,包括分區鍵的選擇、分區策略等。

四:分區介紹

目前MySQL支持一下四種類型的分區:

  • RANGE分區:基於一個給定區間邊界,得到若干個連續區間範圍,按照分區鍵的落點,把數據分配到不同的分區;
  • LIST分區:類似RANGE分區,區別在於LIST分區是基於枚舉出的值列表分區,RANGE是基於給定連續區間範圍分區;
  • HASH分區:基於用户自定義的表達式的返回值,對其根據分區數來取模,從而進行記錄在分區間的分配的模式。這個用户自定義的表達式,就是MySQL希望用户填入的哈希函數。
  • KEY分區:類似於按HASH分區,區別在於KEY分區只支持計算一列或多列,且使用MySQL 服務器提供的自身的哈希函數。
如果表存在主鍵或者唯一索引時,分區列必須是唯一索引的一個組成部分,即將分區字段和唯一索引創建組合索引。

1:RANGE分區

如下創建一個test1表,創建三個分區,當time字段值小於1704038400時放入part0分區,當time字段值小於1735660800時放入part1分區,其餘數據放入part2分區

CREATE TABLE `test1` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
    `time` int(11) NOT NULL DEFAULT 0 COMMENT '時間',
    PRIMARY KEY (`id`,`time`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY RANGE (time) PARTITIONS 3 (
PARTITION part0 VALUES LESS THAN (1704038400), 
PARTITION part1 VALUES LESS THAN (1735660800),
PARTITION part2 VALUES LESS THAN MAXVALUE
);

2:LIST分區

如下創建一個test2表,創建兩個分區,將status值為0和1的放入part0分區,將status值為2和3的放入part1分區

CREATE TABLE `test2` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
    `status` tinyint(2) NOT NULL DEFAULT 0 COMMENT 'status',
    PRIMARY KEY (`id`,`status`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY LIST(status) (
        PARTITION part0 VALUES IN (0,1),
        PARTITION part1 VALUES IN (2,3)
);
LIST分區沒有類似如“VALUES LESS THAN MAXVALUE”這樣的包含其他值在內的定義。所以將要匹配的任何值都必須在值列表中能夠找到

3:HASH分區

如下創建一個test3表,並創建三個HASH分區,在HASH分區中,MySQL自動完成分配記錄到區間的工作,你所要做的只是確定一個用來做哈希的字段或者表達式,以及指定被分區的表將要被分割成的分區數量

CREATE TABLE `test3` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
    `status` tinyint(2) NOT NULL DEFAULT 0 COMMENT 'status',
    PRIMARY KEY (`id`,`status`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY HASH (status) PARTITIONS 3;
  • hash分區的字段不能太複雜,否則插入將會有性能的影響
  • hash分區的優勢在對單條數據的查找,範圍查找的性能不如RANGE分區
  • hash分區只支持數字分區,或用表達式將字符串轉成數字

4:KEY分區

如下創建一個test4表,並創建三個KEY分區,key分區類似於hash分區,本質區別是hash分區使用的是用户自定義的表達式,而key分區函數是由MySQL 服務器提供的,不同的存儲引擎使用不同的內部函數。 創建key分區的語法和hash分區差不多

CREATE TABLE `test4` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
    `status` tinyint(2) NOT NULL DEFAULT 0 COMMENT 'status',
    PRIMARY KEY (`id`,`status`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY KEY (status) PARTITIONS 3;

KEY分區和HASH分區區別

  1. 關鍵字由HASH替換為KEY,例如PARTITION BY KEY()
  2. KEY中包含0個或者多個列名。如果一個表有主鍵的話那麼任何被用於key分區的列必須是表中主鍵的一部分。若表中有定義主鍵,且key分區中不包含任何一個列名,則表的主鍵列將會被用於key分區

五:分區注意事項

  1. MySQL中的分區在禁止空值(NULL)上沒有進行處理。在RANGE分區中,無論是插入一個列值為NULL或者表達式值為NULL的記錄,都被當作是小於任何其他值,會默認被保存在從低到高排好序的第一個分區。在LIST分區中,如果所有分區LIST列表值裏都沒有NULL值,則插入含有NULL值的記錄時會報錯。在hash和key分區中NULL值則都當作0處理。
  2. 一個表最多能有1024個分區,在5.7版本及以上可以有8196個分區
  3. 常見的InnoDB 、 MyISAM引擎都支持分區

六:分區常用操作sql

1:刪除分區並刪除數據

alter table test(表名) drop partition p1(分區名);

2:刪除分區的數據,保留分區

alter table test(表名) truncate partition p1(分區名);

3:移除整個表的分區,不刪除數據

alert table test(表名) remove PARTITIONING ;
user avatar xiangfacaideshubao 头像 l7luo 头像 zhuyundataflux 头像
点赞 3 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.