萬盛學電腦網

 萬盛學電腦網 >> 數據庫 >> mysql教程 >> MySQL表分區注意事項

MySQL表分區注意事項

MySQL表分區注意事項是什麼呢,表分區的注意事項還是比較重要了,我們下面就一起來了解一下吧,具體的步驟如下文介紹。

1、分區列索引約束
若表有primary key或unique key,則分區表的分區列必須包含在primary key或unique key列表裡,這是為了確保主鍵的效率,否則同一主鍵區的東西一個在A分區,一個在B分區,顯然會比較麻煩。

2、各分區類型條件
range 每個分區包含那些分區表達式的值位於一個給定的連續區間內的行。這些區間要連續且不能相互重疊

list只支持整形字段或返回整形數的表達式,每個分區列表裡的值列表必須整數

hash類型只支持整形字段或返回整形數的表達式

key類型只支持列名形式(可一個或多個列名),不支持表達式

3、分區可用函數
ABS()

CEILING() (see CEILING() and FLOOR(), immediately following this list)

DAY()

DAYOFMONTH()

DAYOFWEEK()

DAYOFYEAR()

DATEDIFF()

EXTRACT()

FLOOR() (see CEILING() and FLOOR(), immediately following this list)

HOUR()

MICROSECOND()

MINUTE()

MOD()

MONTH()

QUARTER()

SECOND()

TIME_TO_SEC()

TO_DAYS()

WEEKDAY()

YEAR()

YEARWEEK()

注意:

因為分區函數不包括FROM_UNIXTIME函數,所以用時間戳轉時間來分區就無法實現了,只能用date或者datetime來分區

例如按年我們可以用:

PARTITION BY RANGE (YEAR(date))

按月:

PARTITION BY RANGE(date div 100)   

#div 會把日期變成整數,例如:2014-12-01 -> 20141201、100就是從後面去掉兩位,最後結果是201412

一個訂單做分區的例子:

CREATE TABLE `order` (
  `order_id` bigint(19) NOT NULL DEFAULT '0' COMMENT '訂單ID:年月日時分秒12位+7位隨機數',
  `date` date NOT NULL DEFAULT '0000-00-00' COMMENT '訂單日期',
  `amount` int(11) DEFAULT NULL COMMENT '支付金額,單位分',
  `status` tinyint(1) DEFAULT '0' COMMENT '0:等待支付 1:支付成功 2:支付失敗 3:驗證失敗',
  `addtime` int(10) DEFAULT NULL COMMENT '訂單添加時間',
  PRIMARY KEY (`order_id`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
因為我們沒法用時間戳來做按時間分區,所以添加了一個date字段,這個字段和order_id一起作為主鍵,我們知道分區的列一定要放到主鍵裡面去的。下面我們用date計算成年月組合來分區

ALTER TABLE order PARTITION BY RANGE( date DIV 100)
(
    PARTITION p_2014_06 VALUES LESS THAN (201407),
    PARTITION p_2014_07 VALUES LESS THAN (201408),
    PARTITION p_2014_08 VALUES LESS THAN (201409),
    PARTITION p_2014_09 VALUES LESS THAN (201410),
    PARTITION p_2014_10 VALUES LESS THAN (201411),
    PARTITION p_catch_all VALUES LESS THAN MAXVALUE
);
以上 LESS THAN MAXVALUE 設置了最後一個分區p_catch_all,所以不能用add的方式來添加分區了,以下語句不可用:

ALTER TABLE order ADD PARTITION (PARTITION p_2014_11 VALUES LESS THAN (201412));
只能把最後的p_catch_all分區拆分成兩個,這樣還有一個好處就是在p_catch_all分區的數據不會丟失。數據的合並與拆分用REORGANIZE PARTITION進行。

alter table order reorganize partition p_catch_all into
(
    partition p_2014_11 values less than (201412),
    partition p_catch_all values less than maxvalue
);
合並分區:

alter table order reorganize partition p_2014_10,p_2014_11,p_catch_all into
(
    partition p_catch_test values less than MAXVALUE
);
為什麼不分到p_catch_all去?因為會報分區以存在。

為什麼合並的時候要帶上最後一個分區p_catch_all?因為除了最後一個分區,其他重組的分區范圍不能改變總范圍。

刪除分區但是不刪除數據:

alter table 表名 remove partitioning
注意:上面語句在5.5可以執行,5.6好像有問題,要先測試一下

分區之後,where條件是一個范圍的話分區是不起作用的,如 where date >= '2014-01-01' And date <= '2014-01-31'

一定要用 = 或者 in 條件才行 where date = '2014-01-01' 或者 where date in ('2014-01-01', '2014-01-02', '2014-01-03'...)

copyright © 萬盛學電腦網 all rights reserved