MySQL基数为NULL值

时间:2015-07-21 17:29:36

标签: mysql indexing

这是一张真正的桌子。说我有这段代码:

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 个答案:

答案 0 :(得分:4)

来自MySQL文档here

  

基数是根据存储为整数的统计数据计算的,因此即使对于小型表格,该值也不一定精确

这意味着NULL值不会作为重复项存储在有意义的列中。 NULL不是未知的值。因此没有两个NULL是相等的。

参考here

编辑:这就是为什么你不能将SQL中的NULL值与你总是必须使用=的{​​{1}}进行比较

结论:基数12是正确的。

编辑:我忘了回答你的其他问题了。

这会增加索引的大小吗?答案在MySQL文档中

  

UNIQUE索引创建一个约束,使索引中的所有值必须是不同的。如果您尝试添加具有与现有行匹配的键值的新行,则会发生错误。此约束不适用于除BDB存储引擎之外的NULL值。对于其他引擎,UNIQUE索引允许包含NULL的列的多个NULL值。如果为UNIQUE索引中的列指定前缀值,则列值必须在前缀中唯一。

一旦我使用空字符串而不是NULL值,基数就会下降。哪个是首选值?这样没有首选值。如果空字符串适合您的目的使用它们。基数下降是因为空字符串=空字符串是正确的但 NULL = NULL 不是