开发者社区 问答 正文

云数据库 OceanBase中的NULL值处理

[backcolor=transparent]NULL值视为0
对于分区禁止在空值(NULL)上没有进行处理,无论它是一个列值还是一个用户定义表达式的值。一般而言,在这种情况下把 NULL 视为 0。如果你希望回避这种做法,你应该在设计表时不允许空值;最可能的方法是,通过声明列“NOT NULL”来实现这一点。
说明:此处的 NULL 值,是指表达式计算结果为 NULL,当作 0 处理。
[backcolor=transparent]举例
如果插入一行到按照 RANGE 分区的表,该行用来确定分区的列值为 NULL,分区将把该 NULL 值视为 0。例如,考虑下面的两个表,表的创建和插入记录如下: mysql> CREATE TABLE tnrange (
     -> id INT,
     -> name VARCHAR(5)
     -> )
     -> PARTITION BY RANGE(id) (
     -> PARTITION p1 VALUES LESS THAN (1),
     -> PARTITION p2 VALUES LESS THAN MAXVALUE
     -> );
mysql> INSERT INTO tnrange VALUES (NULL, 'jim');
mysql> SELECT * FROM tnrange;
+------+------+
| id | name |
+------+------+
| NULL | jim |
+------+------+
1 row in set (0.00 sec)


在表 tnrange 中,id 列没有声明为“NOT NULL”,这意味着它们允许 Null 值。可以通过删除这些分区,然后重新运行 SELECT 语句,来验证这些行被保存在每个表的 p1 分区中: mysql> ALTER TABLE tnrange DROP PARTITION p1;
Query OK, 0 rows affected (0.16 sec)

mysql> SELECT * FROM tnrange;
Empty set (0.00 sec)


在按 HASH 分区的情况下,任何产生 NULL 值的表达式都视同好像它的返回值为 0。我们可以通过先创建一个按 HASH 分区的表,然后插入一个包含有适当值的记录,再检查对文件系统的作用,来验证这一点。假定有使用下面的语句在测试数据库中创建了一个表 tnhash: CREATE TABLE tnhash (
id INT,
name VARCHAR(5)
)
PARTITION BY HASH(id)
     PARTITIONS 2;


现在在表 tnhash 中插入一行id列值为 NULL 的行,然后验证该行已经被插入 mysql> INSERT INTO tnhash VALUES (NULL, 'sam');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM tnhash;
+------+------+
| id | name |
+------+------+
| NULL | sam |
+------+------+
1 row in set (0.01 sec)


对于任意的整数 N,NULL MOD N 的值总是等于 NULL。这个结果在确定正确的分区方面被认为是 0。回到系统 shell(仍然假定 bash 用于这个目的) ,通过再次列出数据文件,可以看出值被成功地插入到第一个分区(默认名称为 p0)中: mysql> SELECT * FROM tnhash partition(p0);
+------+------+
| id | name |
+------+------+
| NULL | sam |
+------+------+
1 row in set (0.00 sec)

展开
收起
云栖大讲堂 2017-11-01 14:15:24 2127 分享 版权
阿里云 AI 助理回答

从您的描述来看,您正在讨论的是数据库中NULL值在分区表中的处理方式,特别是针对MySQL数据库。在MySQL的分区表中,如果分区键(即用来决定数据存储在哪个分区的列或表达式)计算结果为NULL,MySQL会将这个NULL值当作0来处理。这意味着:

  1. RANGE分区:当插入一行数据,其分区键为NULL时,MySQL会将NULL视为最小值,通常落入第一个分区(除非该分区的定义排除了NULL或0)。在您的示例中,tnrange表的记录被存入了p1分区。

  2. HASH分区:对于HASH分区,任何产生NULL值的表达式会被视作返回值为0进行处理。因此,当插入id为NULL的行到tnhash表时,由于HASH函数处理NULL如同处理0,这一行数据会被分配到基于0的哈希值所对应的分区中。在您的案例里,它被正确地插入并可以通过查询特定分区看到。

为了避免NULL值在分区判断上的这种默认行为,最佳实践是在设计表结构时明确指定相关列为NOT NULL,从而不允许这些列包含NULL值。这样可以确保分区逻辑更加清晰和可控,避免因NULL值导致的数据分布不符合预期。

总结来说,MySQL在处理分区表时,对NULL值采取的是一种简化处理逻辑,即将NULL视为0,这在某些场景下可能会影响到数据的组织和查询效率,特别是在依赖于精确分区边界或期望NULL值有特定处理逻辑时。通过合理设计表结构,可以有效管理NULL值对分区操作的影响。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答