与自动增加数字相比,电子邮件地址是否不适合作为主键?
我们的Web应用程序需要在系统中唯一使用电子邮件地址。因此,我想将电子邮件地址用作主键。然而,我的同事建议字符串比较速度较慢于整数比较。
这是不使用电子邮件作为主键的有效理由吗?
我们正在使用PostgreSQL
。
与自动增加数字相比,电子邮件地址是否不适合作为主键?
我们的Web应用程序需要在系统中唯一使用电子邮件地址。因此,我想将电子邮件地址用作主键。然而,我的同事建议字符串比较速度较慢于整数比较。
这是不使用电子邮件作为主键的有效理由吗?
我们正在使用PostgreSQL
。
字符串比较比整数比较慢。但是,如果您仅使用电子邮件地址从数据库中检索用户,则这并不重要。如果您有包含多个连接的复杂查询,则这很重要。
如果您将有关用户的信息存储在多个表中,则用户表的外键将是电子邮件地址。这意味着您会多次存储电子邮件地址。
我还要指出,将电子邮件作为唯一字段是不明智的选择,因为有些人甚至小型企业共用一个电子邮件地址。而且,像电话号码一样,电子邮件也可能被重复使用。 比如jsmith@somecompany.com可能一年后属于John Smith,两年后属于Julia Smith。
另一个问题是,电子邮件经常发生变化。如果您将其作为键与其他表连接,那么您还需要更新其他表,当整个客户公司更改其电子邮件时,这可能会对性能产生相当大的影响(我见过这种情况发生)。
主键应该是唯一且不变的。
电子邮件地址像季节一样变化。虽然作为查找的辅助键很有用,但却不是主键的好选择。
使用电子邮件地址作为主键的缺点:
在进行连接操作时速度较慢。
任何带有已发布外键的其他记录现在都具有更大的值,占用更多磁盘空间。(考虑到当今磁盘空间的成本,这可能是一个微不足道的问题,除非记录现在需要更长时间来读取。参见#1)
电子邮件地址可能会更改,这将迫使使用此作为外键的所有记录进行更新。由于电子邮件地址并不经常更改,因此性能问题可能不大。更大的问题是您必须确保提供它。如果您必须编写代码,则需要更多工作,并引入出错的可能性。如果您的数据库引擎支持“on update cascade”,那么这只是一个小问题。
使用电子邮件地址作为主键的优势:
您可以完全消除一些连接。如果您从“主记录”中所需的仅是电子邮件地址,则使用抽象整数键,您必须进行连接才能检索它。如果键是电子邮件地址,则您已经拥有它,连接是不必要的。这是否有所帮助取决于该情况有多常发生。
在进行自由查询时,人类可以轻松看到正在引用哪个主记录。这在尝试跟踪数据问题时可能非常有帮助。
您几乎肯定需要在电子邮件地址上建立索引,因此将其作为主键消除了一个索引,从而改善了插入的性能,因为现在只需更新一个索引而不是两个。
在我看来,这并不是一个显然的选择。当存在实用的自然键时,我倾向于使用它们,因为它们更容易使用,并且缺点在大多数情况下并不真正重要。
..../Users/my@email.com
。如果你不想公开用户的电子邮件地址,你就需要找到其他识别用户的方式,可能是通过唯一的整数值来创建URL(如..../Users/1
)。然后,你最终还是得到了一个唯一的整数值。这很糟糕。假设某个电子邮件提供商停业了,用户将希望更改他们的电子邮件地址。如果您使用电子邮件作为主键,所有用户的外键都会复制该电子邮件地址,使更改变得非常困难...
...而且我还没有开始讨论性能方面的考虑。
我不知道在你的设置中是否可能出现问题,但根据你的关系型数据库管理系统(RDBMS)不同,列的值可能是区分大小写的。PostgreSQL文档说:“如果您将某个列声明为UNIQUE或PRIMARY KEY,则隐式生成的索引区分大小写”。换句话说,如果您接受用户输入来搜索具有电子邮件作为主键的表,并且用户提供了“John@Doe.com”,那么您将找不到“john@doe.com”。
这就是级联的作用。如果有人想更改他的电子邮件地址怎么办?您会更改所有外键吗?
使用整数会更好。您还可以将电子邮件列设置为唯一约束。
示例:
CREATE TABLE myTable(
id integer primary key,
email text UNIQUE
);
是的,这是一个糟糕的主键,因为你的用户会想要更新他们的电子邮件地址。