代理 (INT) 键几乎总是比唯一的自然 (VARCHAR) 键(在 MySQL 中)产生更好的性能吗?

cor*_*ath 1 mysql sql primary-key

我正在努力了解 MySQL 数据库表使用什么数据类型。

假设我们有一家图书出版公司,我们需要在 MySQL 数据库中创建一个包含所有图书和作者的数据库。我们有大约 500000 本书。一本书有一个唯一的 ISBN(例如978-3-16-148410-0)。

因此,我们有两种选择来存储我们的书籍:

  1. 创建一个id VARCHAR(24) NOT NULL自然主键列并将我们的 ISBN 存储在那里,或者
  2. 创建一个代理项id INT NOT NULL AUTO_INCREMENT,然后创建一个isbn UNIQUE VARCHAR(24)

据我了解,普遍的共识是不要用VARCHAR(n)作主键,因为进行查找和连接需要更多的存储和性能,通常这对我来说是有意义的。

但是,如果我们所有的操作都是针对 ISBN(SELECT * FROM books WHERE isbn = ?UPDATEDELETE等) - 为什么不使用 作为VARCHAR(24)主键?

我很难理解,如果你有一个不可变的自然键(比如一本书的 ISBN),并且 95% 的数据库操作都需要使用该字段,那么使用总是VARCHAR(24)优于代理键设计吗?

我觉得AUTO_INCREMENT INT这里有一个代理键完全没有意义。它不会带来任何好处。

或者在确定主键时我是否遗漏了一些基本的东西。

Bil*_*win 5

我会使用 ISBN 作为主键。

MySQL默认存储引擎InnoDB中的主键查找比二级索引查找效率更高。

确实,整数比 24 字符 varchar 占用的存储空间更少,但就您而言,我假设您无论如何都必须存储 ISBN。如果您可以使用整数而不是ISBN,那就可以节省存储空间。

上面关于自然键往往会违反唯一性的评论总的来说是一个很好的警告。违规行为通常来自营销部门。;-)

但对于给定的数据集,您可以确保自然键不重复。如果您在阅读图书馆馆藏中的 ISBN 时遇到错误,图书馆员将必须手动解决该问题。但我预计 500,000 本书不会经常发生这种情况。

提示:使用二进制排序规则定义 varchar,进行字符串比较会更快一些。例如:

CREATE TABLE Books (
 isbn varchar(24) COLLATE utf8mb4_bin,
 -- ...other columns...
 PRIMARY KEY (isbn)
) DEFAULT CHARSET=utf8mb4;
Run Code Online (Sandbox Code Playgroud)

  • “……违规行为通常来自营销部门……”——确实如此。 (4认同)