数据库主键

问题描述 投票:0回答:4

我有一个用户表,其中有数亿行,并且有一个字段用户名(varchar),我应该将其设为主键而不是唯一索引吗? 添加额外字段 user_id(int) 并将其作为主键有什么优点或缺点? 我不知道我会在哪里使用 user_id ,除了在连接条件下, int 上的连接比 varchar 上的连接更快? 或者是吗?(因为两个字段都已索引)

更新:假设更改用户名不是一个选项。

database
4个回答
3
投票

首先,我赞同 Frederik 的评论:我坚信不要将任何业务或功能价值归因于表的主键。现在可能没有更改用户名的选项,但也许以后会有。即使没有,最好养成习惯并与所有表格保持一致,而不是混合范例。

使用数字(或以某种方式顺序)主键的第二个原因是插入和更新速度。虽然可以更改此设置,但默认情况下表上的主键也是聚集索引。聚集索引确定表中行的物理顺序,因此乱序插入值会导致数据库引擎将其后面的所有行向下移动,以便将其插入到正确的位置。对于包含数百万行的表,这可能是一个不平凡的插入或更新操作。


3
投票

我更喜欢添加一个额外的字段作为主键。

主要原因是——恕我直言——主键不应该有“商业”价值。 主键只是一个管理项,仅对数据库重要,以便保证完整性。
正如 Brian 已经提到的,通过添加代理主键,您可以(在您的情况下)允许用户毫无问题地更改其用户名。

主键的值永远不应该更改:否则当您有大量外键时,更新可能会变得非常昂贵。 所有这些更改都应级联到相关表。

接下来,一个整数例如是 4 个字节,而你的用户名列要大得多。
这不仅意味着您将在相关表中占用更多空间,而且还意味着您的索引将变得更大。
组成索引的存储桶将包含较少的“记录指针”,这意味着您将拥有更多的存储桶,这意味着您的索引会更慢。


2
投票

我更喜欢数字 PK 的原因是这样我可以轻松地允许更改用户名。

如果用户名也是主键,则意味着当用户名更改时,与该用户相关的所有记录也必须更改。

请注意,您的数据库可以通过多种方式为数字 PK 生成正确的 ID。 在 MySQL 上,它向字段添加“auto_increment”属性,在 Postgres 和 Oracle 上,它是通过序列添加的。

如果您有数亿行,那么您认为使用用户名可能会更好,这是正确的。 我尽量避免让变体 PK 在表之间浮动,这只会让那些跟随我进入代码的人更难维护整个事情,除非绝对必要。


0
投票

我会在现有键中添加另一列。 向现有主键添加附加字段也称为串联主键。

https://www.relationaldbdesign.com/database-analysis/module2/concatenated-primary-keys.php

© www.soinside.com 2019 - 2024. All rights reserved.