我有一个用户表,其中有数亿行,并且有一个字段用户名(varchar),我应该将它作为主键而不是唯一索引吗?添加额外字段user_id(int)并使其成为主键的优点和缺点是什么?我没有看到我在哪里使用user_id,除了在连接条件上说int上的连接比varchar上的连接更快?或是吗?(因为两个字段都已编入索引)
更新:假设更改用户名不是一个选项。
答案 0 :(得分:3)
我希望添加一个额外的字段作为主键。
主要原因是-imho-主键应该没有“商业”价值。主键只是一个管理项,它只对数据库很重要,因此可以保证完整性 正如Brian已经提到的那样,通过添加代理主键,您可以 - 在您的情况下 - 允许用户更改其用户名而不会出现问题。
永远不应更改主键的值:否则,当您拥有大量外键时,更新可能会变得非常昂贵。所有这些更改应该级联到相关表格。
接下来,一个整数例如是4个字节,而你的usename列则要大得多
这不仅意味着您将在相关表格中占用更多空间,而且还意味着您的索引会变得更大。
构成索引的桶将包含更少的“记录指针”,这意味着你将拥有更多的桶,这意味着你的索引会更慢。
答案 1 :(得分:3)
首先,我是Frederik的第二条评论:我坚信不会将任何业务或功能价值归于表的主键。现在可能没有更改用户名的选项,但也许稍后会有。即使不是这样,最好养成习惯并与所有表格保持一致,而不是混合范式。
使用数字(或以某种方式顺序)主键的第二个原因是插入和更新速度。虽然可以更改,但默认情况下,表上的主键也是聚簇索引。聚簇索引确定表中行的物理顺序,因此不按顺序插入值会导致数据库引擎在其后面移动所有行,以便它可以将其插入到正确的位置。使用包含数百万行的表,这可能是一个非常重要的插入或更新操作。
答案 2 :(得分:2)
我更喜欢数字PK的原因是我可以轻松地允许更改用户名。
如果用户名也是主键,则意味着当用户名更改时,还必须更改与该用户相关的所有记录。
请注意,您的数据库可以通过多种方式为数字PK生成正确的ID。在MySQL上,它会在字段中添加“auto_increment”属性,在Postgres和Oracle上通过序列添加。
如果您有数亿行,那么您可能更好地使用用户名是正确的。我尽量避免让变体PK在表之间浮动,它只会让那些跟我进入代码的人更难维护,除非绝对必要。
答案 3 :(得分:0)
我会在现有密钥中添加另一列。 向现有主键添加附加字段也称为连接主键。
http://www.relationaldbdesign.com/relational-database-analysis/module2/concatenated-primary-keys.php