|
msysql> delimiter // 模式進(jìn)入
Create Table: CREATE TABLE `log_role_gold_change_bak` (
`username` varchar(50) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`roleid` bigint(20) NOT NULL,
`changecount` int(10) NOT NULL,
`newcount` int(10) NOT NULL,
`reason` varchar(20) NOT NULL,
`format_time` varchar(20) NOT NULL,
`create_time` int(10) NOT NULL,
PRIMARY KEY (`id`)
)
圖:4-1

當(dāng) 被分區(qū)的字段沒有在主鍵上時(shí),會(huì)出現(xiàn)上圖(4-1)這樣的錯(cuò)誤。
修改sql:alert table log_role_gold_change_bak drop primary key,add primary key(`id`,`roleid`);
圖:4-2

Reorganize of range partitions cannot change total ranges except for last partition where it can extend the range
(重組的范圍分區(qū)不能改變總范圍除了最后一個(gè)分區(qū),可以擴(kuò)展范圍)
如果 想把原來的 分區(qū)重新分區(qū)的話,必須是在原來的分區(qū)里面選擇。 //這句沒看懂的話 接著往下看(圖4-4)
仔細(xì)看上圖兩次 alter 的不同區(qū)別;然后再看此圖。
圖:4-3

所以如果要是第一次 分區(qū)以后 過了一段時(shí)間 想重新分區(qū)的話,就可以這樣做了,把最大的那個(gè)分區(qū) 在分裂就行了。如上圖
然后要是看創(chuàng)建分區(qū)的 結(jié)構(gòu)執(zhí)行:
MySQL> show create table log_role_gold_change_bak\G;
*************************** 1. row ***************************
Table: log_role_gold_change_bak
Create Table: CREATE TABLE `log_role_gold_change_bak` (
`username` varchar(50) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`roleid` bigint(20) NOT NULL,
`changecount` int(10) NOT NULL,
`newcount` int(10) NOT NULL,
`reason` varchar(20) NOT NULL,
`create_time` int(10) NOT NULL,
PRIMARY KEY (`id`,`roleid`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (`roleid`)
(PARTITION p1 VALUES LESS THAN (110) ENGINE = InnoDB index directory='/data/testpath/path1/idx'
data directory='/data/testpath/path1/data',
PARTITION p2 VALUES LESS THAN (10010) ENGINE = InnoDB index directory='/data/testpath/path2/idx' data directory='/data/testpath/path2/data',
PARTITION p3 VALUES LESS THAN (10011) ENGINE = InnoDB index directory='/data/testpath/path3/idx' data directory='/data/testpath/path3/data',
PARTITION p4 VALUES LESS THAN MAXVALUE ENGINE = InnoDB index directory='/data/testpath/path4/idx' data directory='/data/testpath/path4/data') */
1 row in set (0.00 sec)
綠色:代表索引目錄,藍(lán)色代表數(shù)據(jù)目錄
目錄必須有 mysql 讀寫 權(quán)限 chown -R mysql:mysql 路徑;
、、、、、、、、、、、仔細(xì)看下面的 幾個(gè)、、、、、、、、、、、、、、、、、、、、、
圖4-4

可以看出如果想把s1,s2,s3,s4 重新分割的話,重新分區(qū)的 最后一列(p2)必須大于等于重新分割的老分區(qū)的一列(s2)
最后結(jié)果為:
圖4-5

總結(jié) : “多分一” ,“ 一分多” 可以直接分區(qū),但是 多分多的話,要注意分區(qū)范圍了。
比如:
======一對(duì)多===多對(duì)一====
less than 10
less than 100 《========》 p1 values less than (10) 或者 less than maxvalue 或者 100 或者101
less than maxvalue
======多對(duì)多=======
s1 values less than 10 p1 values less than 5
s2 values less than 100 《========》 p2 values less than (100) 或者 less than maxvalue 或者101
s3 values less than maxvalue
**************end*************
ALTER TABLE log_role_gold_change_bak ADD PARTITION (PARTITION s5 VALUES LESS THAN (100000000));
這條sql 語句 只有在 沒有 maxvalue 時(shí) 才有效, 否則執(zhí)行時(shí) 會(huì)報(bào)錯(cuò);
圖4-6

針對(duì)時(shí)間進(jìn)行分區(qū) 看下圖的不同:
圖4-7

mysql5.5新的函數(shù)中增加了一個(gè)COLUMNS關(guān)鍵詞,如果你想使用MySQL 5.1中的分區(qū)類型(range),那你必須將類型轉(zhuǎn)換成整數(shù),需要使用一個(gè)額外的查找表,到了MySQL 5.5中,你可以不用再進(jìn)行類型轉(zhuǎn)換了,所以columns 字段是 為了不再進(jìn)行類型轉(zhuǎn)換而加的,所以 第一個(gè)sql報(bào)錯(cuò)了。第二個(gè)sql 用了 year 函數(shù) 轉(zhuǎn)換了。
下面這個(gè)圖:
explain partitions 這個(gè)是用來 查找當(dāng)前的sql 用到了哪個(gè)分區(qū),下面(圖4-8)的貌似有問題 partitions 那個(gè)模塊指向的參數(shù)是 s02,我認(rèn)為應(yīng)該是s03的 有知道的話給說下
圖4-8

通過上面的幾個(gè)圖片看出一種結(jié)果就是 一個(gè)表里 只能對(duì)一個(gè)字段進(jìn)行分區(qū),(如上面 第一次給 roleid分區(qū),第二次給 create_time分區(qū))如果給另個(gè)字段,會(huì)把之前的覆蓋掉。
warming:
圖4-9

使用YEAR或TO_DAYS定義一個(gè)分區(qū)的確讓人費(fèi)解,查詢時(shí)不得不使用赤裸列,因?yàn)榧恿撕瘮?shù)的查詢不能識(shí)別分區(qū)。
如果這時(shí)候 你想 通過 alter table log_role_gold_change_bak drop primary key,add primary key(`id`,`format_time`); 來改變 主鍵上的字段,這樣是不行的,會(huì)報(bào)如下錯(cuò)。
A PRIMARY KEY must include all columns in the table's partitioning function, 和在增加分區(qū)主鍵上沒有字段 報(bào)的錯(cuò)是一樣的。
這里報(bào)錯(cuò)的原因是 因?yàn)?nbsp; 你已經(jīng)在這個(gè)字段上創(chuàng)建分區(qū)了。所以要想在主鍵上增加新的字段分區(qū),必須先刪除之前的分區(qū)。sql: alter table log_role_gold_change_bak
remove partitioning; 然后再使用上面的sql進(jìn)行增加 主鍵分區(qū)字段。如下圖:
圖4-10

這樣就行了。
mysql> alter table log_role_gold_change_bak partition by range columns(`format_time`)( -- columns 5.5 才支持的
-> partition s1 values less than ('2013-07-02 10:39:56'),
-> partition s2 values less than ('2015-07-02 10:39:56'),
-> partition s3 values less than (maxvalue)
-> )
-> //
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 109839
Current database: lszm_reku1
Query OK, 11 rows affected (0.32 sec)
Records: 11 Duplicates: 0 Warnings: 0
測(cè)試:
mysql> explain partitions select * from log_role_gold_change_bak where format_time <='2013-07-02 10:39:56';//
+----+-------------+--------------------------+------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------------------+------------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | log_role_gold_change_bak | s1,s2 | ALL | NULL | NULL | NULL | NULL | 12 | Using where |
+----+-------------+--------------------------+------------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> select * from log_role_gold_change_bak where format_time <='2013-07-02 10:39:56';//
+----------------------------------+----+--------+-------------+----------+---------+---------------------+-------------+
| username | id | roleid | changecount | newcount | reason | format_time | create_time |
+----------------------------------+----+--------+-------------+----------+---------+---------------------+-------------+
| 6A376EC1A57BDEA109B63FAA89D4376C | 1 | 0 | 0 | 0 | getmail | 2012-07-02 10:39:56 | 1341196796 |
+----------------------------------+----+--------+-------------+----------+---------+---------------------+-------------+
1 row in set (0.00 sec)
成功了, 所以mysql 5.5 的 columns 這個(gè)關(guān)鍵字 很有用啊(COLUMNS關(guān)鍵字現(xiàn)在允許字符串和日期列作為分區(qū)定義列)。這里 可以看出 此查詢 只是在s1,s2 中進(jìn)行了查找,因?yàn)?nbsp; 小于2013-07-02 10:39:56 的 只能在s1,s2 分區(qū)中查找
下面對(duì)多個(gè)字段進(jìn)行分區(qū):
alter table log_role_gold_change_bak partition by range columns(`id`,`roleid`)(
partition s1 values less than (5,100),
partition s2 values less than (30,170),
partition s3 values less than (150,1100),
partition s4 values less than (450,maxvalue),
partition s5 values less than (maxvalue,maxvalue)
)
當(dāng)?shù)谝粋€(gè)值小于分區(qū)定義的第一個(gè)范圍時(shí),那么該行將屬于這里了。
mysql> explain partitions select * from log_role_gold_change_bak where id=5 and roleid=100;//
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+-------------+------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+-------------+------+-------+
| 1 | SIMPLE | log_role_gold_change_bak | s2 | const | PRIMARY | PRIMARY | 12 | const,const | 1 | |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+-------------+------+-------+
1 row in set (0.00 sec)
mysql> select * from log_role_gold_change_bak where id=5 and roleid=100;//
+----------------------------------+----+--------+-------------+----------+--------------------+---------------------+-------------+
| username | id | roleid | changecount | newcount | reason | format_time | create_time |
+----------------------------------+----+--------+-------------+----------+--------------------+---------------------+-------------+
| C56F6C6EE70A0986F4C543549F1CAAC4 | 5 | 100 | -4 | 2 | all_server_cup_egg | 2014-05-22 13:37:25 | 1400737045 |
+----------------------------------+----+--------+-------------+----------+--------------------+---------------------+-------------+
1 row in set (0.00 sec)
-- 沒有這條信息所以 下面的都為null
mysql> select * from log_role_gold_change_bak where id=30 and roleid=11100;//
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 111802
Current database: lszm_reku1
Empty set (0.22 sec)
mysql> explain partitions select * from log_role_gold_change_bak where id=30 and roleid=11100;//
+----+-------------+-------+------------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+-----------------------------------------------------+
1 row in set (0.00 sec)
因?yàn)?查的是固定的 某一行所以為 s3區(qū)
mysql> explain partitions select * from log_role_gold_change_bak where id=30 and roleid=11101;//
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+-------------+------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+-------------+------+-------+
| 1 | SIMPLE | log_role_gold_change_bak | s3 | const | PRIMARY | PRIMARY | 12 | const,const | 1 | |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+-------------+------+-------+
1 row in set (0.00 sec)
mysql> explain partitions select * from log_role_gold_change_bak where id=151 and roleid=1100;//
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 111865
Current database: lszm_reku1
+----+-------------+-------+------------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+-----------------------------------------------------+
1 row in set (0.19 sec)
mysql> explain partitions select * from log_role_gold_change_bak where id=150 and roleid=1100;//
+----+-------------+-------+------------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+-----------------------------------------------------+
1 row in set (0.00 sec)
當(dāng)?shù)谝粋€(gè)值小于分區(qū)定義的第一個(gè)范圍時(shí),那么該行將屬于這里了。
mysql> explain partitions select * from log_role_gold_change_bak where id=28 and roleid=11011;//
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+-------------+------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+-------------+------+-------+
| 1 | SIMPLE | log_role_gold_change_bak | s2 | const | PRIMARY | PRIMARY | 12 | const,const | 1 | |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+-------------+------+-------+
1 row in set (0.00 sec)
由于小于 28的 有s1 ,s2
mysql> explain partitions select * from log_role_gold_change_bak where id <28 and roleid<11011;//
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 111926
Current database: lszm_reku1
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | log_role_gold_change_bak | s1,s2 | range | PRIMARY | PRIMARY | 4 | NULL | 14 | Using where |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.19 sec)
//雖然 150 屬于s3 范圍 但是 10010101 不屬于此范圍 ,所以往下查找(這時(shí)150就不管查找范圍內(nèi)了,只看 roleid的查找范圍了。)
當(dāng)?shù)谝粋€(gè)值和第二個(gè)值等于他們對(duì)應(yīng)的范圍時(shí),如果元組不小于定義的范圍,那么它就不屬于這里,繼續(xù)下一步
mysql> explain partitions select * from log_role_gold_change_bak where id=150 and roleid=10010101;//
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+-------------+------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+-------------+------+-------+
| 1 | SIMPLE | log_role_gold_change_bak | s4 | const | PRIMARY | PRIMARY | 12 | const,const | 1 | |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+-------------+------+-------+
1 row in set (0.00 sec)
//再次驗(yàn)證了 當(dāng)查找范圍是 如果第一個(gè)判斷值小于某一個(gè)分區(qū)的返回的第一個(gè)值,那么就在此分區(qū)了
mysql> explain partitions select * from log_role_gold_change_bak where id<5 and roleid<10010101;//
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | log_role_gold_change_bak | s1 | range | PRIMARY | PRIMARY | 4 | NULL | 2 | Using where |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> explain partitions select * from log_role_gold_change_bak where id<30 and roleid<10010101;//
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | log_role_gold_change_bak | s1,s2 | range | PRIMARY | PRIMARY | 4 | NULL | 14 | Using where |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> explain partitions select * from log_role_gold_change_bak where id<150 and roleid<10010101;//
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | log_role_gold_change_bak | s1,s2,s3 | range | PRIMARY | PRIMARY | 4 | NULL | 74 | Using where |
+----+-------------+--------------------------+------------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.01 sec)
可以看下面的幾個(gè)圖片:
轉(zhuǎn)載于:http://images.51cto.com/files/uploadimg/20100222/102648467.jpg
圖1

圖2

圖3

圖4

SELECT
partition_name part,
partition_expression expr,
partition_description descr,
table_rows
FROM
INFORMATION_SCHEMA.partitions
WHERE
TABLE_SCHEMA = schema()
AND TABLE_NAME='log_role_gold_change_bak';
通過這個(gè)sql 可以看出當(dāng)前每個(gè)分區(qū)里的
大約的行數(shù)。 如果存儲(chǔ)引擎是InnoDB,上面的值就是一個(gè)近似值,如果你需要確切的值,那你就不能信任它們。如果是myisam 那就是確切的行數(shù)。
清空某一分區(qū),但是留下分區(qū)結(jié)構(gòu):
alter table log_role_gold_change_baktruncate partition s1//
mysql> show create table log_role_gold_change_bak\G;
*************************** 1. row ***************************
Table: log_role_gold_change_bak
Create Table: CREATE TABLE `log_role_gold_change_bak` (
`username` varchar(50) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`roleid` bigint(20) NOT NULL,
`changecount` int(10) NOT NULL,
`newcount` int(10) NOT NULL,
`reason` varchar(20) NOT NULL,
`format_time` varchar(20) NOT NULL,
`create_time` int(10) NOT NULL,
PRIMARY KEY (`id`,`roleid`)
) ENGINE=InnoDB AUTO_INCREMENT=502 DEFAULT CHARSET=utf8
/*!50500 PARTITION BY RANGE COLUMNS(id,roleid)
(PARTITION s1 VALUES LESS THAN (5,100) ENGINE = InnoDB,
PARTITION s2 VALUES LESS THAN (30,170) ENGINE = InnoDB,
PARTITION s3 VALUES LESS THAN (150,1100) ENGINE = InnoDB,
PARTITION s4 VALUES LESS THAN (450,MAXVALUE) ENGINE = InnoDB,
PARTITION s5 VALUES LESS THAN (MAXVALUE,MAXVALUE) ENGINE = InnoDB) */
1 row in set (0.00 sec)
-> //
ERROR 1065 (42000): Query was empty
//刪除某一分區(qū)
mysql> alter table log_role_gold_change_bak
drop partition s1//
Query OK, 0 rows affected (0.15 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table log_role_gold_change_bak\G;
*************************** 1. row ***************************
Table: log_role_gold_change_bak
Create Table: CREATE TABLE `log_role_gold_change_bak` (
`username` varchar(50) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`roleid` bigint(20) NOT NULL,
`changecount` int(10) NOT NULL,
`newcount` int(10) NOT NULL,
`reason` varchar(20) NOT NULL,
`format_time` varchar(20) NOT NULL,
`create_time` int(10) NOT NULL,
PRIMARY KEY (`id`,`roleid`)
) ENGINE=InnoDB AUTO_INCREMENT=502 DEFAULT CHARSET=utf8
/*!50500 PARTITION BY RANGE COLUMNS(id,roleid)
(PARTITION s2 VALUES LESS THAN (30,170) ENGINE = InnoDB,
PARTITION s3 VALUES LESS THAN (150,1100) ENGINE = InnoDB,
PARTITION s4 VALUES LESS THAN (450,MAXVALUE) ENGINE = InnoDB,
PARTITION s5 VALUES LESS THAN (MAXVALUE,MAXVALUE) ENGINE = InnoDB) */
1 row in set (0.00 sec)
注意上面標(biāo)紅的。
|