本文目錄一覽:
mysql分表的3種方法介紹,什麼是分區
可以看mysql的data文件夾下面的數據庫文件,就可以查看當前分區情況。還有幾種獲取MySQL分區表信息的常用方法SHOW CREATE TABLE 可以查看創建分區表的CREATE語句 SHOW TABLE STATUS 可以查看錶是否為分區表 查看INFORMATION_SCHEMA.PARTITIONS表 可以查看錶具有哪幾個分區、分區的方法、分區中數據的記錄數等重要信息
如何對zabbix mysql做分區表
關於zabbix和MySQL分區表 – 支持zabbix 2.0和2.2,mysql在有外鍵的表不支持分區表。在zabbix 2.0和2.2中history和trend表沒有使用外鍵,因此是可以在這些表中做分區的。
Index changes:
1.如果zabbix的數據庫已經有了數據,更改索引可能需要一些時間,根據具體的數據量,需要的時間長短也不一樣。
2.在某些版本的MySQL索引的改變會使整個表上讀鎖。貌似mysql 5.6沒有這個限制。
所述第一步驟是修改幾個索引以允許做分區,按照下面的命令:
mysql
Alter table history_text drop primary key, add index (id), drop index
history_text_2, add index history_text_2 (itemid, id);
Query OK, 0 rows affected (0.49 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql
Alter table history_log drop primary key, add index (id), drop index
history_log_2, add index history_log_2 (itemid, id);
Query OK, 0 rows affected (2.71 sec)
Records: 0 Duplicates: 0 Warnings: 0
Stored Procedures:
下面開始填寫存儲過程,需要執行下面的幾個存儲過程語句,只要能看到”Query OK, 0 rows affected (0.00 sec)”只能就沒有什麼問題了。
十、MySQL表分區
表分區是將⼀個表的數據按照⼀定的規則⽔平劃分為不同的邏輯塊,並分別進⾏物理存儲,這個規則就叫做分區函數,可以有不同的分區規則。5.7可以通過show plugins語句查看當前MySQL是否⽀持表分區功能。
但當表中含有主鍵或唯⼀鍵時,則每個被⽤作 分區函數的字段必須是表中唯⼀鍵和主鍵的全部或⼀部分 ,否則就⽆法創建分區表。⽐如下⾯的表由於唯⼀鍵和主鍵沒有相同的字段,所以⽆法創建表分區
上述例⼦中刪除唯⼀鍵,確保主鍵中的字段包含分區函數中的所有字段,創建成功
或者將主鍵擴展為包含ref字段
表分區的主要優勢在於:
可以允許在⼀個表⾥存儲更多的數據,突破磁盤限制或者⽂件系統限制
對於從表⾥將過期或歷史的數據移除在表分區很容易實現,只要將對應的分區移除即可
對某些查詢和修改語句來說,可以 ⾃動 將數據範圍縮⼩到⼀個或⼏個表分區上,優化語句執⾏效率。⽽且可以通過 顯示指定表分區 來執⾏語句,⽐如 SELECT * FROM t PARTITION (p0,p1) WHERE c 5
表分區類型分為:
範圍表分區,按照⼀定的範圍值來確定每個分區包含的數據,分區函數使⽤的字段必須只能是 整數類型,分區的定義範圍必須是連續的,且不能有重疊部分,通過使⽤VALUES LESS THAN來定義分區範圍,表分區的範圍定義是從⼩到⼤定義的
⽐如:
Store_id6的數據被放在p0分區⾥,6=store_id10之間的數據被放在p1分區⾥,以此類推,當新插⼊的數據為(72, ‘Mitchell’, ‘Wilson’, ‘1998-06-25’, NULL, 13) 時,則新數據被插⼊到p2分區⾥,但當插⼊的數據的store_id為21時,由於沒有分區去容納此數據,所以會報錯,我們需要修改⼀下表的定義
報錯:
修改表的定義:
MAXVALUE關鍵詞的作⽤是表示可能的最⼤值,所以任何store_id=16的數據都會被寫⼊到p3分區⾥。分區函數中也可以使⽤表達式 ,⽐如:
對timestamp字段類型可以使⽤的表達式⽬前僅有unix_timestamp ,其他的表達式都不允許
列表表分區,按照⼀個⼀個確定的值來確定每個分區包含的數據,通過PARTITION BY LIST(expr)分區函數表達式必須返回整數,取值範圍通過VALUES IN (value_list)定義
對List表分區來說,沒有MAXVALUE特殊值,所有的可能取值都需要再VALUES IN中包含,如果有未定義的取值則會報錯
同樣,當有主鍵或者唯⼀鍵存在的情況下,分區函數字段需要包含在主鍵或唯⼀鍵中
對range和list表分區來說,分區函數可以包含多個字段,分區多字段函數(column partition) 所涉及的字段類型可以包括:
範圍多字段分區函數與普通的範圍分區函數的區別在於:
a) 字段類型多樣化
b) 範圍多字段分區函數 不⽀持表達式,只能⽤字段名
c) 範圍多字段分區函數⽀持⼀個或多個字段
再⽐如創建如下的表分區:
對多列對⽐來說:
當然只要保證取值範圍是增⻓的,表分區就能創建成功,⽐如:
但如果 取值範圍不是增⻓的,就會返回錯誤 :
對其他數據類型的⽀持:
list列表多字段表分區,例如:你有一個在12個城市客戶的業務, 為了銷售和市場的目的, 你的組織每3個城市劃分為一個區域針對LIST COLUMNS分區, 你可以基於城市的名稱創建一個客戶數據表並聲明4個分區當你的客戶在對應的這個區域:
使用日期分區
但是這種情況在日期增長到非常大的時候是很複雜的, 所以這種還是使用RANGE 分區方式比較好
按照⼀個⾃定義的函數返回值來確定每個分區包含的數據,這個 ⾃定義函數也可以僅僅是⼀個字段名字
通過PARTITION BY HASH (expr)⼦句來表達哈希表分區,其中的 expr表達式必須返回⼀個整數,基於分區個數的取模(%)運算。根據餘數插⼊到指定的分區
對哈希表分區來說只需要定義分區的個數,其他的事情由內部完成
如果沒有寫明PARTITIONS字段,則默認為1,表達式可以是整數類型字段,也可以是⼀個函數,⽐如
⽐如: CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY HASH( YEAR(col3) ) PARTITIONS 4;
如果插⼊⼀條數據對應的col3為‘2005-09-15’時,則插⼊數據的分區計算⽅法為:
與哈希表分區類似,只不過哈希表分區依賴於⾃定義的函數,⽽key表分區的哈希算法是依賴MySQL本身, CREATE TABLE … PARTITION BY KEY () 創建key表分區, 括號⾥⾯可以包含0個或者多個字段,所引⽤的字段必須是主鍵或者主鍵的⼀部分 ,如果括號⾥⾯沒有字段,則代表使⽤主鍵
如果表中沒有主鍵但有唯⼀鍵,則使⽤唯⼀鍵,但 唯⼀鍵字段必須定義為not null ,否則報錯
所引⽤的字段未必必須是整數類型,其他的類型也可以使⽤,⽐如:
⼦表分區,是在表分區的基礎上再創建表分區的概念, 每個表分區下的⼦表分區個數必須⼀致 ,⽐如:
ts表擁有三個範圍分區,同時每個分區都各⾃有兩個⼦分區,所以總共有6個分區
⼦表分區必須是範圍/列表分區+哈希/key⼦表分區的組合
⼦表分區也可以顯示的指定⼦表分區的名字,⽐如:
不同的表分區對NULL值的處理⽅式不同
對範圍表分區來說,如果插⼊的是NULL值,則將數據放到最⼩的分區表⾥
對list表分區來說,⽀持NULL值的唯⼀情況就是某個分區的允許值中包含NULL
對哈希表分區和Key表分區來說,NULL值會被當成0值對待
通過alter table命令可以執⾏增加,刪除,重新定義,合併或者拆分表分區的管理動作
對範圍表分區和列表表分區來說,刪除⼀個表分區命令如下:
刪除表分區的動作不光會把分區刪掉,也會把表分區⾥原來的數據給刪除掉
在原分區上增加⼀個表分區可以通過alter table … add partition語句來完成
但對範圍表分區來說,增加的表分區必須在尾部增加,在頭部或者在中間增加都會失敗:
為解決這個問題,可以使⽤ REORGANIZE 命令:
對列表表分區來說,只要新增加的分區對應的值在之前的表分區中沒有出現過,就可以通過alter table… add partition來增加
當然, 也可以通過REORGANIZE命令將之前的多個分區合併成⼀個或⼏個分區,但要保持分區值⼀致:
更複雜的⽐如將多個分區重組成多個分區:
MySQL分區表簡介
我們的業務只存近一段時間的數據,因此有大量表需要清理 歷史 數據,目前使用的delete清理數據,存在以下問題。為避免同時支持大量delete,我們的清理任務只在低峰期串行執行,導致任務過多時需要排隊,甚至失敗的情況;數據清理使用delete語句,表數據量較大時,對數據庫造成很大壓力;即使我們刪除了舊數據,已刪除的數據仍佔據存儲空間,底層數據文件並沒有立刻變小,以至於形成數據空洞。
查看MySQL官方文檔時,發現了分區表,因此基於官方文檔總結一下。
MySQL邏輯上為一個表,物理上存儲在多個文件中,這是 MySQL 支持的功能(5.1 開始), 8.0 版本只 InnoDB 和 NDB 支持分區表。
優點:
缺點:
根據分區表鍵值的範圍把數據存儲到表的不同分區中,適用於以時間或日期作為分區類型,方便數據清理。
小提示:
1.當插入數據分區不存在時會報錯:Table has no partition for value xxx;
2.Range類型分區字段必須是數值,時間類型可用函數轉換為數值;
3.分區字段列值可以為null,所有為null的數據將存在最小的分區中;
按分區鍵取值的列表進行分區,每一行數據須找到對應的分區列表,否則數據插入失敗
小提示:
根據指定分區表達式的整數值以及分區數進行數據劃分(mod函數)
小提示:
按鍵分區類似於按哈希分區,只是哈希分區使用用戶定義的表達式,用於鍵分區的哈希函數由 MySQL 服務器提供。NDB 集群為此使用 MD5() ; 對於使用其他存儲引擎的表,服務器使用自己的內部哈希函數。
小提示:
子分區(subpartitioning)也稱為複合分區(composite partitioning) ,是已分區表中每個分區的進一步劃分
小提示:
小提示:
Mysql分區表Partition
一、背景
話說風和日麗的一天,為提高隨着業務增長的大表(3510449行吧)的訪問效率,於是決定對錶分區,記錄如下。
二、實操
結合業務,若干條記錄會集中在一個日期,查詢時也往往只查詢一個日期內的數據,於是選取分區字段為時間。
創建分區 比如
CREATE TABLE message_all (
id int(10) NOT NULL AUTO_INCREMENT,
……
createtime datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘創建時間’
PRIMARY KEY ( id , createtime )
) ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY RANGE (YEAR(createtime))
(PARTITION p2015 VALUES LESS THAN (2016) ENGINE = InnoDB,
PARTITION p2016 VALUES LESS THAN (2017) ENGINE = InnoDB,
PARTITION p2017 VALUES LESS THAN (2018) ENGINE = InnoDB,
PARTITION p2018 VALUES LESS THAN MAXVALUE ENGINE = InnoDB)
不過我們表已經有了當然不能這麼建,除非你想導一次數據。
如下操作 :
1、
ALTER TABLE message_all PARTITION BY RANGE (to_days(createtime))
(
PARTITION p2015 VALUES LESS THAN (to_days(‘2016-01-01’)),
PARTITION p2016 VALUES LESS THAN (to_days(‘2017-01-01’)),
PARTITION p2017 VALUES LESS THAN (to_days(‘2018-01-01’)),
PARTITION p2018 VALUES LESS THAN MAXVALUE
);
或者
2、ALTER TABLE message_all PARTITION BY RANGE (YEAR(createtime))
(
PARTITION p2015 VALUES LESS THAN (YEAR(‘2016-01-01’))
);
然後追加。
ALTER TABLE message_all ADD PARTITION
(
PARTITION p2016 VALUES LESS THAN (YEAR(‘2017-01-01’)),
PARTITION p2017 VALUES LESS THAN (YEAR(‘2018-01-01’)),
PARTITION p2018 VALUES LESS THAN MAXVALUE
);
這裡會有幾種錯誤情況:
1、ALTER TABLE message_all PARTITION BY RANGE (to_days(createtime)) ;
[Err] 1492 – For RANGE partitions each partition must be defined
解釋:必須指定至少一個分區。
2、[Err] 1492 – A PRIMARY KEY must include all columns in the table’s partitioning function
解釋:分區字段必須是主鍵之一。
3、[Err] 1492 – Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
解釋:分區字段為timestamp,換成datetime。
4、[Err] 1526 – Table has no partition for value xxxx
解釋:用追加方式第一次必須覆蓋目前所有數據。
總結:
1、創建時必須指定至少一個分區。
2、key必須為主鍵之一。
3、RANGE處必須為INT型,時間字段用函數轉——YEAR()、YEARWEEK()、TO_DAYS()。
4、THAN處必須為INT型,時間字段用函數轉——TO_DAYS、TO_SECONDS()、UNIX_TIMESTAMP()。
5、它就是以兩個INT比大小劃分的文件。
6、所有ENGINE必須一樣。
7、範圍分區添加只能在最大值後面追加。
8、分區是有上限的貌似1024個。
用到的其他操作
1、刪除分區(直接扔掉分區文件,數據也沒了)
ALTER TABLE message_all DROP PARTITION p2016;
2、清空分區數據
ALTER TABLE message_all TRUNCATE PARTITION p2017;
3、重定義(可實現:分區拆分、合併、重命名)
ALTER TABLE message_all REORGANIZE PARTITION p201601,p201602,p201603,p201604 INTO
(
PARTITION p2016012 VALUES less than(TO_DAYS(‘2016-03-01’)),
PARTITION p2016034 VALUES less than(TO_DAYS(‘2016-05-01’))
);
檢查/查看你的分區
1、SHOW TABLE STATUS LIKE ‘message_all’;
2、SELECT * FROM information_schema.partitions WHERE table_name=’message_all’;
3、SHOW CREATE TABLE message_all;
4、EXPLAIN SELECT COUNT(1) FROM message_all WHERE createtime= ‘2016-01-01’ AND createtime ‘2016-12-30’;如果用到了分區partitions里會有顯示。
5、指定分區查
SELECT COUNT(1) FROM message_all PARTITION (p2016) 表別名 WHERE ……;
到這裡就結束啦,土豆白。
一些概念
水平分區Partition有以下幾種模式
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/244518.html