MySQL中NULL值的基数

3

这是一个真实表格的复制。假设我有以下代码:

CREATE TABLE `testTable` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`col` varchar(10) CHARACTER SET utf8 DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `testTable` (col) VALUES (NULL), ('a'), (NULL), ('b'), (NULL), ('c'), (NULL), ('d'), (NULL), ('e'), (NULL), ('f');
ALTER TABLE `testTable` ADD INDEX (`col`);
OPTIMIZE TABLE `testTable`;
SHOW INDEX FROM `testTable`;

我理解

+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table     | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| testTable |          0 | PRIMARY  |            1 | id          | A         |          12 |     NULL | NULL   |      | BTREE      |         |               |
| testTable |          1 | col      |            1 | col         | A         |          12 |     NULL | NULL   | YES  | BTREE      |         |               |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

为什么col的基数是12而不是7?有7个唯一值,为什么所有的NULL都被单独计算?这会增加索引的大小吗?只要我使用空字符串而不是NULL值,基数就会下降。哪一个是首选值?

1个回答

5
从MySQL文档这里可知:
基于存储为整数的统计数据进行计算,因此即使对于小表,该值也不一定是精确的。
这意味着在列中未存储空值作为重复项,这是有道理的。 NULL不是已知的值。因此没有两个NULL相等。
请参阅此处
编辑:这就是为什么你不能使用=比较SQL中的NULL值,你必须始终使用is NULL
结论:Cardinality 12 是正确的。
编辑:我忘记回答你的其他问题了。 这会增加索引的大小吗?答案在MySQL文档中。
唯一索引创建一个约束,使得索引中的所有值都必须不同。如果尝试添加与现有行匹配的键值的新行,则会出现错误。对于BDB存储引擎以外的其他引擎,除了BDB存储引擎,此约束不适用于NULL值。对于在唯一索引中为列指定前缀值的情况,列值必须在前缀内唯一。 只要我使用空字符串而不是NULL值,基数就会下降。哪个值更合适?没有什么特别合适的值。如果空字符串对您的目的有用,请使用它们。基数下降是因为空字符串=空字符串是正确的,但NULL=NULL不是这样。

基数是根据存储为整数的统计数据进行计算的。这是否意味着甚至 VARCHAR 值也无法正确计数? - Patrick St.Onge
不,这意味着统计数据存储为整数,而不是数据本身。因此,在像 NULL 这样的边缘情况下,统计数据很可能会出错。我还编辑了我的答案来回答您的其他问题。 - Shreyas Chavan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接