刚刚上网搜索了这个问题——为什么My SQL的表需要主键?没有找到合适的解释,我的强迫症就上来了,发誓解决这个问题。上天不负有心人,随我一起进入知识的海洋吧。
隐含的主键
如果表中没有主键,将会造成下面的可能性结果:If you do not define a PRIMARY KEY for your table,
MySQL locates the first UNIQUE index where all the key columns are NOT NULL and InnoDB uses it as the clustered index.
MYSQL 8.0 MANUAL: 15.6.2.1 CLUSTERED AND SECONDARY INDEXES, 28TH JUNE 2019
If the table has no PRIMARY KEY or suitable UNIQUE index,
InnoDB internally generates a hidden clustered index named GEN_CLUST_INDEX on a synthetic column containing row ID values.
The rows are ordered by the ID thatInnoDB assigns to the rows in such a table.
The row ID is a 6-byte field that increases monotonically as new rows are inserted.
Thus, the rows ordered by the row ID are physically in insertion order.
MYSQL 8.0 MANUAL: 15.6.2.1 CLUSTERED AND SECONDARY INDEXES, 28TH JUNE 2019
第一段话的意思是没有主键My SQL会自动将表中第一个具有 unique and not null约束的字段作为主键。
这样会造成很恶心的后果,如果没有写主键,那我们在创建表格的时候就要小心了。要注意先创建哪个字段再创建哪个字段。这无疑会增加我们的工作量。
第二段主要是告诉我们,如果数据库没有合适的具有唯一性约束的字段作为主键,那么数据库将会自动生成一个GEN_CLUST_INDEX作为主键。
快速的查询
创建一个下面的表:CREATE TABLE t (
a INTEGER UNSIGNED,
b INTEGER UNSIGNED,
c INTEGER UNSIGNED,
d INTEGER UNSIGNED,
PRIMARY KEY (a, b),
INDEX idx_c (c)
) ENGINE InnoDB;
若给其中的字段赋值,则实际存储结果会像这样:行实际上由主键列(id)排序。
a | b | c | d |
---|---|---|---|
1 | 0 | 1 | 3 |
1 | 2 | 5 | 6 |
2 | 1 | 1 | 0 |
3 | 1 | 5 | 4 |
4 | 5 | 2 | 0 |
4 | 6 | 1 | 7 |
但是如果按照其他字段来查找信息,这个字段会先找到主键,再由主键确定所需信息。这样下来相当于绕了一圈又回到主键,在通过主键去确定信息。
方便的日志记录
推荐的二进制记录格式为行。那就意味着:- insert:整个行都需要被记录;
- delete:记录已删除的行的主键值;
- update:修改的行的主键值和新的列值将会被记录;
通过主键来记录删除和更新是非常快的,没有主键的话,所有的表的更新和删除就会变慢,因为需要扫描整个表来达到这种效果。
基于上面的种种,所以现在My SQL是强制在表中创建主键的。