这是一张真正的桌子。说我有这段代码:
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值,基数就会下降。哪个是首选值?
答案 0 :(得分:4)
来自MySQL文档here
基数是根据存储为整数的统计数据计算的,因此即使对于小型表格,该值也不一定精确
这意味着NULL值不会作为重复项存储在有意义的列中。 NULL不是未知的值。因此没有两个NULL是相等的。
参考here
编辑:这就是为什么你不能将SQL中的NULL值与你总是必须使用=
的{{1}}进行比较
结论:基数12是正确的。
编辑:我忘了回答你的其他问题了。
这会增加索引的大小吗?答案在MySQL文档中
UNIQUE索引创建一个约束,使索引中的所有值必须是不同的。如果您尝试添加具有与现有行匹配的键值的新行,则会发生错误。此约束不适用于除BDB存储引擎之外的NULL值。对于其他引擎,UNIQUE索引允许包含NULL的列的多个NULL值。如果为UNIQUE索引中的列指定前缀值,则列值必须在前缀中唯一。
一旦我使用空字符串而不是NULL值,基数就会下降。哪个是首选值?这样没有首选值。如果空字符串适合您的目的使用它们。基数下降是因为空字符串=空字符串是正确的但 NULL = NULL 不是