在MySQL中,分区没有禁止任何操作零
作为分区表达式的值,无论它是列值还是用户提供的表达式的值。尽管它被允许使用零
由于表达式的值必须在其他情况下产生整数,因此记住这一点很重要零
不是一个数字。MySQL的分区实现处理零
比任何非零
价值,就像命令
所做的事。
这意味着治疗零
不同类型的分区之间存在差异,如果没有做好准备,可能会产生您意想不到的行为。在这种情况下,我们将在本节讨论每种MySQL分区类型是如何处理的零
值,并为每个分区提供示例。
使用RANGE分区处理NULL。如果将一行插入到按范围
这样,用于确定分区的列值为零
时,将该行插入最低的分区。考虑数据库中的这两个表p
,创建如下:
mysql> CREATE TABLE t1 (-> c1 INT, -> c2 VARCHAR(20) -> PARTITION BY RANGE(c1) (-> PARTITION p0 VALUES LESS THAN (0), -> PARTITION p1 VALUES LESS THAN (10), -> PARTITION p2 VALUES LESS THAN MAXVALUE ->);查询OK, 0 rows affected (0.09 sec) mysql> CREATE TABLE t2 (- > c1 INT, -> c2 VARCHAR(20) ->) -> PARTITION BY RANGE(c1) (- > PARTITION p0 VALUES LESS THAN (-5), -> PARTITION p1 VALUES LESS THAN (0), -> PARTITION p2 VALUES LESS THAN (10), -> PARTITION p3 VALUES LESS THAN MAXVALUE ->);查询OK, 0行受影响(0.09秒)
您可以看到这两者创建的分区创建表
语句,使用以下查询对分区
表中的INFORMATION_SCHEMA
数据库:
mysql> SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTHWHERE TABLE_SCHEMA = 'p' AND TABLE_NAME LIKE 't_';+------------+----------------+------------+----------------+-------------+ | TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | +------------+----------------+------------+----------------+-------------+ | t1 | p0 | 0 | 0 | 0 | | t1 | p1 | 0 | 0 | 0 | | t1 | p2 | 0 | 0 | 0 | | t2 | p0 | 0 | 0 | 0 | | t2 | p1 | 0 | 0 | 0 | | t2 | p2 | 0 | 0 | 0 | | t2 | p3 | 0 | 0 | 0 | +------------+----------------+------------+----------------+-------------+ 7行集(0.00秒)
(有关此表的详细信息,请参见Section 24.3.16,“INFORMATION_SCHEMA PARTITIONS Table”)。现在让我们用包含a的单行填充每个表零
中用作分区键的列,并验证行是否使用一对选择
声明:
mysql> INSERT INTO t1 VALUES (NULL, 'mothra');mysql> INSERT INTO t2 VALUES (NULL, 'mothra');mysql> SELECT * FROM t1;+------+--------+ | id |名称 | +------+--------+ | 零|摩斯拉也 | +------+--------+ 1行组(0.00秒)mysql >选择从t2 *;+------+--------+ | id |名称 | +------+--------+ | 零|摩斯拉也 | +------+--------+ 1行集(0.00秒)
通过重新运行前面的查询,可以看到使用哪些分区来存储插入的行INFORMATION_SCHEMA。分区
检查输出:
mysql> SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTHWHERE TABLE_SCHEMA = 'p' AND TABLE_NAME LIKE 't_';+------------+----------------+------------+----------------+-------------+ | TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | +------------+----------------+------------+----------------+-------------+| t1 | p0 | 1 | 20 | 20 || t1 | p1 | 0 | 0 | 0 | | t1 | p2 | 0 | 0 | 0 || t2 | p0 | 1 | 20 | 20 || t2 | p1 | 0 | 0 | 0 | | t2 | p2 | 0 | 0 | 0 | | t2 | p3 | 0 | 0 | 0 | +------------+----------------+------------+----------------+-------------+ 7行集(0.01秒)
还可以通过删除这些分区来演示这些行存储在每个表的最低分区中,然后重新运行选择
声明:
ALTER TABLE t1 DROP PARTITION p0mysql> ALTER TABLE t2 DROP PARTITION p0mysql> SELECT * FROM t1;mysql> SELECT * FROM t2;空集(0.00秒)
(获取更多信息修改表…删除分区
,请参阅第13.1.8节“ALTER TABLE语句”)。
零
对于使用SQL函数的分区表达式也是这样处理的。假设我们使用a定义一个表创建表
这样的语句:
CREATE TABLE tndate (id INT, dt DATE) PARTITION BY RANGE(年份)(分区p0值小于(1990),分区p1值小于(2000),分区p2值小于MAXVALUE);
和其他MySQL函数一样,(空)
返回零
.带有dt
的列值零
是否将分区表达式计算为小于任何其他值的值,从而将其插入分区p0
.
使用LIST分区处理NULL。分区的表列表
承认零
值,当且仅当其中一个分区是使用包含的值列表定义的零
.与之相反的是一个表被列表
哪个没有明确使用零
在值列表中拒绝导致零
值,如下例所示:
mysql> CREATE TABLE ts1 (-> c1 INT, -> c2 VARCHAR(20) ->) -> PARTITION BY LIST(c1) (-> PARTITION p0 VALUES IN (0,3,6), -> PARTITION p1 VALUES IN (1,4,7), -> PARTITION p2 VALUES IN (2,5,8) ->);mysql> INSERT INTO ts1 VALUES (9, 'mothra');错误1504 (HY000): mysql> INSERT INTO ts1 VALUES (NULL, 'mothra');错误1504 (HY000):表没有NULL值的分区
只有带有c1
值之间0
而且8
包容性可以插入壹空间
.零
在这个范围之外,就像数字一样9
.我们可以创建表格ts2
而且ts3
值列表包含零
,如图所示:
mysql> CREATE TABLE ts2 (-> c1 INT, -> c2 VARCHAR(20) ->) -> PARTITION BY LIST(c1) (-> PARTITION p0 VALUES IN (0,3,6), -> PARTITION p1 VALUES IN (1,4,7), -> PARTITION p2 VALUES IN (2,5,8), -> PARTITION p3 VALUES IN (NULL) ->);查询OK, 0 rows affected(0.01秒)mysql> CREATE TABLE ts3 (-> c1 INT, -> c2 VARCHAR(20) ->) -> PARTITION BY LIST(c1) (-> PARTITION p0 VALUES IN (0,3,6), -> PARTITION p1 VALUES IN (1,4,7, NULL), -> PARTITION p2 VALUES IN (2,5,8) ->);查询OK, 0行受影响(0.01秒)
在为分区定义值列表时,您可以(并且应该)处理零
就像对待其他价值一样。例如,两者(null)中的值
而且(1,4,7, null)中的值
都是有效的吗(1, null, 4,7)中的值
,(null, 1,4,7)中的值
等等。您可以插入一行零
为列c1
每一张表ts2
而且ts3
:
INSERT INTO ts2 VALUES (NULL, 'mothra');mysql> INSERT INTO ts3 VALUES (NULL, 'mothra');查询确定,影响1行(0.00秒)
通过对。发出适当的查询INFORMATION_SCHEMA。分区
,您可以确定使用哪些分区来存储刚刚插入的行(与前面的示例一样,我们假设分区表是在p
数据库):
mysql> SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTHWHERE TABLE_SCHEMA = 'p' AND TABLE_NAME LIKE 'ts_';+------------+----------------+------------+----------------+-------------+ | TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | +------------+----------------+------------+----------------+-------------+ | ts2 | p0 | 0 | 0 | 0 | | ts2 | p1 | 0 | 0 | 0 | | ts2 | p2 | 0 | 0 | 0 || ts2 | p3 | 1 | 20 | 20 || ts3 | p0 | 0 | 0 | 0 || ts3 | p1 | 1 | 20 | 20 || ts3 | p2 | 0 | 0 | 0 | +------------+----------------+------------+----------------+-------------+ 7行集(0.01秒)
如本节前面所示,还可以通过删除这些分区,然后执行a来验证哪些分区用于存储这些行选择
.
用HASH和KEY分区处理NULL。零
是处理有些不同的表分区哈希
或关键
.在这些情况下,产生a的任何分区表达式零
Value被视为它的返回值为零。我们可以通过检查创建分区表对文件系统的影响来验证这种行为哈希
并用包含适当值的记录填充它。假设你有一张表th
(亦在p
数据库)使用以下语句创建:
mysql> CREATE TABLE th (-> c1 INT, -> c2 VARCHAR(20) -> PARTITION BY HASH(c1) -> PARTITIONS 2;查询OK, 0行受影响(0.00秒)
属于这个表的分区可以使用下面显示的查询查看:
mysql> SELECT TABLE_NAME,PARTITION_NAME,TABLE_ROWS,AVG_ROW_LENGTH,DATA_LENGTHWHERE TABLE_SCHEMA =' p' AND TABLE_NAME ='th';+------------+----------------+------------+----------------+-------------+ | TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | +------------+----------------+------------+----------------+-------------+ | th | p0 | 0 | 0 | 0 | | | p1 | 0 | 0 | 0 | +------------+----------------+------------+----------------+-------------+ 2行集(0.00秒)
TABLE_ROWS
每个分区都是0。现在插入两行th
谁的c1
列值为零
和0,并验证这些行是否被插入,如下所示:
mysql> INSERT INTO th VALUES (NULL, 'mothra'), (0, 'gigan');mysql> SELECT * FROM th (0.00 sec)+------+---------+ | c1 | c2 | +------+---------+ | 零|摩斯拉也 | +------+---------+ | 0 | gigan | +------+---------+ 2行集(0.01秒)
回想一下,对于任何整数N
的值。零模
总是N
零
.对于按哈希
或关键
,此结果被处理为确定正确的分区0
.检查INFORMATION_SCHEMA。分区
表中,我们可以看到两行都被插入到分区中p0
:
mysql> SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTHWHERE TABLE_SCHEMA =' p' AND TABLE_NAME ='th';+------------+----------------+------------+----------------+-------------+ | TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | +------------+----------------+------------+----------------+-------------+| th | p0 | 2 | 20 | 20 || | p1 | 0 | 0 | 0 | +------------+----------------+------------+----------------+-------------+ 2行集(0.00秒)
通过重复上一个例子使用按键分区
代替按哈希分区
在表的定义中,您可以验证这一点零
对于这种类型的分区,也被视为0。