mysql的主键索引为什么不能null

mysql的主键索引为什么不能null

  • 官方文档对null的描述
  • 再看官方文档对 primary key索引的说明
  • 这里的设计其实也是为了符合规范SQL1992
  • 题外话:唯一索引和null

这是一个非常奇怪且有趣的问题。可以通过官方文档进行解读

https://dev.mysql.com/doc/refman/5.7/en/glossary.html

官方文档对null的描述

A special value in SQL, indicating the absence of data. Any arithmetic operation or equality test involving a NULL value, in turn produces a NULL result. (Thus it is similar to the IEEE floating-point concept of NaN, “not a number”.) Any aggregate calculation such as AVG() ignores rows with NULL values, when determining how many rows to divide by. The only test that works with NULL values uses the SQL idioms IS NULL or IS NOT NULL.

NULL values play a part in index operations, because for performance a database must minimize the overhead of keeping track of missing data values. Typically, NULL values are not stored in an index, because a query that tests an indexed column using a standard comparison operator could never match a row with a NULL value for that column. For the same reason, unique indexes do not prevent NULL values; those values simply are not represented in the index. Declaring a NOT NULL constraint on a column provides reassurance that there are no rows left out of the index, allowing for better query optimization (accurate counting of rows and estimation of whether to use the index).

Because the primary key must be able to uniquely identify every row in the table, a single-column primary key cannot contain any NULL values, and a multi-column primary key cannot contain any rows with NULL values in all columns.

Although the Oracle database allows a NULL value to be concatenated with a string, InnoDB treats the result of such an operation as NULL.

从这个里面我们可以得出答案,null暗示着数据的缺失,对null的算术运算和相等测试得到的结果还会是一个null。null有点类似IEEE 中浮点数的 NAN not a number的概念(其实有很多数都是NAN)。
从这里我们也可以看出: null == null的结果为 null 而不是 true 是缺失的,可以认为null 不是唯一的,就像 IEEE的浮点数 NAN一样,不是只有一个值的是一族值的总称。

这里还有一点提到了: null通常不被放进索引中,这也是为什么索引会因为null而失效。

再看官方文档对 primary key索引的说明

A set of columns—and by implication, the index based on this set of columns—that can uniquely identify every row in a table. As such, it must be a unique index that does not contain any NULL values.

InnoDB requires that every table has such an index (also called the clustered index or cluster index), and organizes the table storage based on the column values of the primary key.

When choosing primary key values, consider using arbitrary values (a synthetic key) rather than relying on values derived from some other source (a natural key).

See Also clustered index, index, natural key, synthetic key.

这里就很清晰了,主键索引是为了,唯一确定每一条数据,null因为缺失,不知道,所以不能唯一确定每一条数据(因为算术运算得到的是null而不是一个确定的值 而是一个null, 只能进行 IS NULL 和 not null进行运算)。

这里的设计其实也是为了符合规范SQL1992

http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt

A unique constraint is satisfied if and only if no two rows in
a table have the same non-null values in the unique columns. In
addition, if the unique constraint was defined with PRIMARY KEY,
then it requires that none of the values in the specified column or
columns be the null value.

说白了也是要符合制定的规范。

题外话:唯一索引和null

唯一索引可以有null值,且可以有多个null值, 因为 null 跟 null进行相等的比较的时候,得到结果是 null。如果 null 跟 null进行相等比较的时候得到的结果是 相等的, 那么唯一索引可以拥有一个null值,而不是多个null值。

你可能感兴趣的:(mysql,数据库)