Mysql 在网站系统的许多表中使用电子邮件地址作为主键是一种好的做法吗?

Mysql 在网站系统的许多表中使用电子邮件地址作为主键是一种好的做法吗?,mysql,database-design,primary-key,Mysql,Database Design,Primary Key,例如,在stackoverflow.com这样的网站上,使用电子邮件地址识别多个表中的用户是否是一种良好的做法 如果主键很长,比如说 瓦查尔(50) 甚至 瓦查尔(100) ?否。首先,如果同一用户问两个问题怎么办?如果电子邮件是主键,我们现在有一个PK冲突 其次,它甚至不应该是复合键的一部分。如果用户更改了他们的电子邮件地址怎么办?然后,需要在表中进行一系列难看的更改 第三,您应该只使用自动递增ID之类的东西。字符串(如电子邮件地址)效率极低 如果需要将问题与特定成员关联,请将memberID

例如,在stackoverflow.com这样的网站上,使用电子邮件地址识别多个表中的用户是否是一种良好的做法

如果主键很长,比如说

瓦查尔(50)

甚至

瓦查尔(100)


否。首先,如果同一用户问两个问题怎么办?如果电子邮件是主键,我们现在有一个PK冲突

其次,它甚至不应该是复合键的一部分。如果用户更改了他们的电子邮件地址怎么办?然后,需要在表中进行一系列难看的更改

第三,您应该只使用自动递增ID之类的东西。字符串(如电子邮件地址)效率极低

如果需要将问题与特定成员关联,请将
memberID
外键放入
member
表中。答案表应该有自己的自动递增ID,在
问题
表中有一个
问题ID
外键,在
成员
表中有一个
成员ID
外键,代表提供答案的成员。等等


顺便说一下,您可能想了解,至少(3NF)。这不是胡闹,这只是很好的常识。

不是真的。对于任何规模较大的数据集,最终都会浪费大量空间,并且在查询时会影响性能。此外,如果有人更改了他们的电子邮件(您可能允许也可能不允许),您必须在任何地方都更改它


一个唯一标识用户的代理键是一个更好的选择。

这是Jay Pipes关于比较主键的int和char之间的差异的文章,可能有助于理解为什么应该使用整数。

不,这是个坏主意。电子邮件会发生变化,字符串比较也相对昂贵。

代理键是最好的。自然键用于教科书。自然键在我所见过的每一个系统上都造成了严重的问题。即使是国家身份证号码也不够唯一


如果您对列进行了正确的索引,大多数现代数据库(Oracle、Postgres、SQLServer)不会因为您加入电子邮件地址而过度惩罚您。如果您担心连接,请创建一个非规范化的物化视图,并在插入/更新时支付费用。

除了不希望字符串作为表中主键的所有性能原因之外,还有几个非常具体的原因,特别是电子邮件不应被用作主键:

  • 主键必须是唯一的。但是,规范化电子邮件地址很困难。在强制实现唯一性方面,您可能会遇到很多问题。(电子邮件地址区分大小写吗?是否忽略。或+内部电子邮件?如何比较非英语电子邮件?)

  • 电子邮件是可识别个人身份的信息。将其用于任何目的都可能是一个安全和隐私问题。特别是如果你的一些用户不满13岁

  • 电子邮件不是一成不变的,因此不应作为身份表示使用。因此,如果用户更改了他们的电子邮件,您必须a)更新所有表的主键,或者b)将旧电子邮件作为密钥进行维护,这使得使用电子邮件作为密钥一开始就毫无用处


如果在网站系统中采用memberID,则会有更多的联接操作。一般规则是在遇到性能问题之前进行规范化,然后根据需要进行反规范化以解决这些问题。基于索引的联接非常有效,特别是如果索引中的外键是漂亮的、小的代理键。@史蒂文:如果外键设计得当并被索引,它会比你想象的快。@Jason:我已经有一段时间没有考虑理论方面了,所以我很可能是错的,但我不认为使用电子邮件地址作为用户的主键真的违反了第三范式,因为电子邮件地址可以被视为候选键。如果在网站系统中采用代理,将有更多的连接操作。这些连接在总体方案中通常非常便宜。而且,现有联接的成本将会降低,因为它们是通过4字节(或8字节)的整数键而不是20字节(或更多)的字符串键联接的。回答得好。完全有可能两个用户共享同一个电子邮件地址(可能是丈夫和妻子?),所以你不能100%确定他们是唯一的。人们获得和丢失电子邮件地址的频率相当高。一些web应用程序还允许帐户更改电子邮件地址并关联多个电子邮件地址。