使用电子邮件地址作为主键有哪些做法?我应该避免它,而是使用自动递增的ID号,还是引擎也能处理它?
MySQL数据库,但我感兴趣的是其他引擎可能如何处理这个(PostgreSQL特别)。
您应该始终有一个唯一的整数主键,该主键没有业务价值。然后将其称为代理密钥。
您应该将电子邮件地址本身存储在另一个字段中,通常带有索引,这样它就可以作为查找的关键字。
这将使您能够提供基于使用电子邮件地址查找来定位用户的功能。此时的任何其他功能都会将该记录主键用于其他操作,例如更新用户地址。
只有在满足一组相当窄的标准时才使用电子邮件地址是完全合理的:
- 电子邮件地址是主要实体,它不会识别其他东西(比如用户帐户)
- 对表的FK引用相对较少,或者无联接的快速FK查找至关重要
- 您不会以任何方式验证电子邮件地址
换句话说,使用电子邮件地址作为主键是非常不合适的。我唯一能想到的明智的情况是处理邮件流的软件,它想记录每个电子邮件地址的统计数据。
如果您想将其用作用户的标识符,请不要这样做。
电子邮件地址本身是主要实体
你不是在使用电子邮件地址来识别其他东西,比如说用户帐户,而是有一个关于电子邮件地址的表格。比如说,你正在跟踪每个地址的邮件发送量。如果你用电子邮件地址识别其他东西,不要将其用作主键。如果没有完全稳定的小而简单的自然密钥,请使用代理密钥。姓名和电子邮件地址更改。
国外关键参考文献相对较少
对以电子邮件地址为主键的表没有太多的FK引用,或者您需要在使用FK的表中进行非常快速且无连接的查找。如果您直接在表中搜索值(电子邮件),而不是在另一个表中连接并测试另一个值,则可以获得巨大的性能优势。另一方面,使用电子邮件地址而不是生成的代理键会增加表所需的存储空间(因此:更大、更慢的表和索引),因此只有当你真的希望大量搜索外键时,这才是值得的。
您不验证电子邮件地址
如果你有"有效"或"无效"电子邮件地址这样的概念,你的规则迟早会改变,如果你使用电子邮件地址作为主键,你将陷入悲惨的境地。
电子邮件地址很奇怪
这三个电子邮件地址是相同的:
user.name@DOMAIN.COM
user.name@DoMAIN.CoM
user.name@domain.com
但这三个都不一样:
user.name@domain.com
USER.NAME@domain.com
User.Name@domain.com
根据相关RFC。一些MTA对此表示赞同,而另一些MTA则对整个事件漠不关心。
是的。不要把它们当作PKs。
使用自动递增的主键。您不需要向用户公开这些信息,您可以将其可视化表示为密钥是电子邮件地址,但您需要内部一致的数字,并且不会随着时间的推移而更改。
记住,你的主键用于链接到其他表,所以如果有人更改了他们的电子邮件地址,你也必须更新所有依赖的链接。这是极难纠正的。
使用什么SQL数据库并不重要,它们的工作方式大致相同,也有相似的局限性。
不使用业务信息作为主键而使用代理主键的一个重要原因是外键。想象一下,某人的电子邮件地址需要更新。你能想象更新密钥中的所有信息会是多么痛苦吗?如果你的外键足够严格,你可能最终不得不制作一个重复的记录,更新所有的子记录,然后删除原始记录。如果您使用代理主键(通常是自动生成的整数)
选择和设计密钥的明智标准是:简单性、熟悉性和稳定性。电子邮件地址对使用它们的人来说既简单又熟悉,而且更改频率相对较低。许多成功的网站和系统都需要唯一的电子邮件地址来识别用户。电子邮件地址对于许多用途来说都是非常好的密钥。
考虑到电子邮件地址是一个合适的密钥,问题是它是否应该是主密钥。主键的选择是指当一个表有多个键,并且出于某种目的您希望选择其中一个作为"首选"键时会出现的情况。关于什么应该或不应该成为主键的想法从根本上来说是主观和武断的。没有健全的理论基础来做出这样的选择,因为被指定为主键的键在形式或功能上不需要与任何其他键有任何不同。仅仅基于人类的偏好,电子邮件地址应该比一个陌生且不相关的递增数字"更好"地选择主键。