这个问题在这里已有答案:
使用电子邮件地址作为主键的做法是什么?我应该避免使用自动递增的ID号,还是引擎能够处理它?
MySQL数据库,但我对其他引擎如何处理这个问题感兴趣(特别是PostgreSQL) .
您应始终拥有一个具有 no business value 的唯一整数主键 . 然后将其称为代理键 .
您应该将电子邮件地址本身存储在另一个字段中,通常使用索引,以便它可以作为查找的键 .
这将使您能够提供基于使用查找的电子邮件地址定位用户的功能 . 此时的任何其他功能然后将该记录主键用于其他操作,例如,更新用户地址 .
仅在符合相当狭窄的标准的情况下使用电子邮件地址是完全合理的:
电子邮件地址是主要实体,它不识别其他内容(比如用户帐户)
对表的FK引用相对较少,或者没有连接的快速FK查找至关重要
您不以任何方式验证电子邮件地址
换句话说,使用电子邮件地址作为主键很少是合适的 . 我能真正想到的唯一情况是处理邮件流的软件,它希望记录有关每个电子邮件地址的统计信息 .
如果您正在考虑将其用作用户的标识符,请不要这样做 .
你're not using an email address to identify something else, like a user account say, but instead have a table that'所有关于电子邮件地址 . 比方说,你用电子邮件地址识别别的东西,不要用它作为主键 . 如果没有完全稳定的小而简单的自然键,请使用代理键 . 姓名和电子邮件地址发生变化 .
对于具有电子邮件地址作为主键的表,没有太多FK引用,或者您需要在具有FK的表中进行非常快速且无连接的查找 . 如果您直接在表中搜索值(电子邮件),而不是加入另一个表并测试另一个表中的值,则可以获得巨大的性能提升 . 另一方面,使用电子邮件地址而不是生成的代理键会增加表所需的存储空间(因此:更大,更慢的表和索引),所以只有你真的希望在外键上搜索很多时才是值得的 .
如果你有一个"valid"或"invalid"电子邮件地址这样的概念,你的规则迟早会改变,并且你使用电子邮件地址作为主键 .
这三个电子邮件地址是相同的:
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同意,其他人对整个事情不区分大小写 .
是啊 . 不要将它们用作PK .
使用自动递增的主键 . 您不需要向用户公开此信息,您可以直观地表示它,就像密钥是电子邮件地址一样,但您需要内部一致且不随时间变化的数字 .
请记住,您的主键用于链接到其他表,因此如果有人更改了他们的电子邮件地址,您还必须更新所有相关链接 . 这很难做到 .
使用什么SQL数据库并不重要,它们的工作方式大致相同,并且具有类似的限制 .
不使用业务信息作为主键而是使用代理主键的一个重要原因是外键 . 想象一下,某人的电子邮件地址需要更新 . 你能想象更新密钥中的所有信息会带来多大的痛苦吗?如果您的外键足够严格,您可能需要制作重复记录,更新所有子记录,然后删除原始记录 . 如果您使用代理主键(通常是自动生成的整数),那么仅仅更新1个记录电子邮件地址要困难得多
选择和设计密钥的明智标准是:简单,熟悉和稳定 . 电子邮件地址对于使用它们的人来说很简单和熟悉,而且它们的变化相对较少 . 许多成功的网站和系统需要唯一的电子邮件地址来识别用户电子邮件地址为许多目的提供了完美的密钥 .
鉴于电子邮件地址是合适的密钥,问题是它应该是主键 . 当一个表有多个键并且您希望为某些目的选择其中一个作为"preferred"时,会出现主键的选择 . 关于应该或不应该成为主键的想法从根本上是主观的和随意的 . 没有合理的理论依据可以做出这样的选择,因为指定为主要的密钥不需要在形式或功能上与任何其他密钥有任何不同 . 仅基于人类偏好,电子邮件地址应该选择主键而不是不熟悉且不相关的递增数字 .
5 回答
您应始终拥有一个具有 no business value 的唯一整数主键 . 然后将其称为代理键 .
您应该将电子邮件地址本身存储在另一个字段中,通常使用索引,以便它可以作为查找的键 .
这将使您能够提供基于使用查找的电子邮件地址定位用户的功能 . 此时的任何其他功能然后将该记录主键用于其他操作,例如,更新用户地址 .
仅在符合相当狭窄的标准的情况下使用电子邮件地址是完全合理的:
电子邮件地址是主要实体,它不识别其他内容(比如用户帐户)
对表的FK引用相对较少,或者没有连接的快速FK查找至关重要
您不以任何方式验证电子邮件地址
换句话说,使用电子邮件地址作为主键很少是合适的 . 我能真正想到的唯一情况是处理邮件流的软件,它希望记录有关每个电子邮件地址的统计信息 .
如果您正在考虑将其用作用户的标识符,请不要这样做 .
电子邮件地址,其自身是主要实体
你're not using an email address to identify something else, like a user account say, but instead have a table that'所有关于电子邮件地址 . 比方说,你用电子邮件地址识别别的东西,不要用它作为主键 . 如果没有完全稳定的小而简单的自然键,请使用代理键 . 姓名和电子邮件地址发生变化 .
外键引用相对较少
对于具有电子邮件地址作为主键的表,没有太多FK引用,或者您需要在具有FK的表中进行非常快速且无连接的查找 . 如果您直接在表中搜索值(电子邮件),而不是加入另一个表并测试另一个表中的值,则可以获得巨大的性能提升 . 另一方面,使用电子邮件地址而不是生成的代理键会增加表所需的存储空间(因此:更大,更慢的表和索引),所以只有你真的希望在外键上搜索很多时才是值得的 .
您无法验证电子邮件地址
如果你有一个"valid"或"invalid"电子邮件地址这样的概念,你的规则迟早会改变,并且你使用电子邮件地址作为主键 .
电子邮件地址很奇怪
这三个电子邮件地址是相同的:
但这三者都不同:
根据相关的RFC . 一些MTA同意,其他人对整个事情不区分大小写 .
是啊 . 不要将它们用作PK .
使用自动递增的主键 . 您不需要向用户公开此信息,您可以直观地表示它,就像密钥是电子邮件地址一样,但您需要内部一致且不随时间变化的数字 .
请记住,您的主键用于链接到其他表,因此如果有人更改了他们的电子邮件地址,您还必须更新所有相关链接 . 这很难做到 .
使用什么SQL数据库并不重要,它们的工作方式大致相同,并且具有类似的限制 .
不使用业务信息作为主键而是使用代理主键的一个重要原因是外键 . 想象一下,某人的电子邮件地址需要更新 . 你能想象更新密钥中的所有信息会带来多大的痛苦吗?如果您的外键足够严格,您可能需要制作重复记录,更新所有子记录,然后删除原始记录 . 如果您使用代理主键(通常是自动生成的整数),那么仅仅更新1个记录电子邮件地址要困难得多
选择和设计密钥的明智标准是:简单,熟悉和稳定 . 电子邮件地址对于使用它们的人来说很简单和熟悉,而且它们的变化相对较少 . 许多成功的网站和系统需要唯一的电子邮件地址来识别用户电子邮件地址为许多目的提供了完美的密钥 .
鉴于电子邮件地址是合适的密钥,问题是它应该是主键 . 当一个表有多个键并且您希望为某些目的选择其中一个作为"preferred"时,会出现主键的选择 . 关于应该或不应该成为主键的想法从根本上是主观的和随意的 . 没有合理的理论依据可以做出这样的选择,因为指定为主要的密钥不需要在形式或功能上与任何其他密钥有任何不同 . 仅基于人类偏好,电子邮件地址应该选择主键而不是不熟悉且不相关的递增数字 .