代码之家  ›  专栏  ›  技术社区  ›  robert

使用电子邮件地址作为主键?

  •  219
  • robert  · 技术社区  · 14 年前

    与自动递增的数字相比,电子邮件地址是否是主要的错误候选地址?

    我们的Web应用程序需要电子邮件地址在系统中是唯一的。所以,我想用电子邮件地址作为主键。但是我的同事建议字符串比较要比整数比较慢。

    不使用电子邮件作为主键是一个有效的理由吗?

    我们正在使用 PostgreSQL .

    25 回复  |  直到 6 年前
        1
  •  273
  •   Sjoerd    14 年前

    字符串比较比int比较慢。但是,如果只使用电子邮件地址从数据库中检索用户,则这并不重要。如果您有具有多个联接的复杂查询,那么这很重要。

    如果在多个表中存储有关用户的信息,则用户表的外键将是电子邮件地址。这意味着您要多次存储电子邮件地址。

        2
  •  172
  •   HLGEM    12 年前

    我还将指出,电子邮件是一个不好的选择,使一个独特的领域,有人,甚至小企业共享一个电子邮件地址。就像电话号码一样, 电子邮件可以重复使用。 jsmith@somecompany.com一年后很容易归属于john smith和julia smith两年后。

    电子邮件的另一个问题是它们经常变化。如果您要用它作为键加入到其他表中,那么您还必须更新其他表,当整个客户公司更改其电子邮件时,这可能会对性能造成很大影响(我已经看到这种情况)。

        3
  •  95
  •   Steven A. Lowe    14 年前

    主键应该是 独特的 常数

    电子邮件地址会像季节一样变化。用作查找的辅助键,但对于主键的选择较差。

        4
  •  62
  •   Jay    14 年前

    使用电子邮件地址作为主键的缺点:

    1. 做连接时变慢。

    2. 任何具有已发布的外键的其他记录现在都有一个更大的值,占用了更多的磁盘空间。(考虑到目前磁盘空间的成本,这可能是一个微不足道的问题,除非记录现在需要更长的时间来读取。参见第1页)

    3. 电子邮件地址可能会更改,这将强制更新所有使用此作为外键的记录。由于电子邮件地址不会经常更改,因此性能问题可能很小。更大的问题是,你必须确保为它做好准备。如果您必须编写代码,这将是更多的工作,并引入错误的可能性。如果您的数据库引擎支持“on update cascade”,这是一个小问题。

    使用电子邮件地址作为主键的优点:

    1. 您可以完全消除一些连接。如果“主记录”中只需要电子邮件地址,那么使用一个抽象的整数键,您必须执行一个连接来检索它。如果密钥是电子邮件地址,那么您已经拥有了它,并且不需要加入。这是否对你有帮助取决于这种情况发生的频率。

    2. 当您执行特殊查询时,很容易让人看到正在引用的主记录。当试图跟踪数据问题时,这是一个很大的帮助。

    3. 无论如何,您几乎肯定需要在电子邮件地址上有一个索引,因此使其成为主键会消除一个索引,从而提高插入的性能,因为插入现在只有一个索引要更新,而不是两个索引要更新。

    在我看来,这也不是一个扣篮。我倾向于在有实用钥匙的情况下使用自然钥匙,因为它们更容易使用,而且缺点在大多数情况下并不重要。

        5
  •  12
  •   meriton    14 年前

    很糟糕。假设某个电子邮件提供商停业。然后,用户将希望更改其电子邮件。如果您已使用电子邮件作为主键,则用户的所有外键都将复制该电子邮件,这使得更改相当困难…

    …我甚至还没有开始讨论性能方面的考虑。

        6
  •  12
  •   xlttj    14 年前

    我不知道这在您的设置中是否是一个问题,但是根据您的RDBMS,列的值可能是 区分大小写 . PostgreSQL文档说:_如果将列声明为唯一键或主键,则隐式生成的索引区分大小写。换句话说,如果您接受用户输入以电子邮件为主键的表中的搜索,并且用户提供了“john@doe.com”,则不会找到“john@doe.com”。

        7
  •  10
  •   Simen Echholt    14 年前

    似乎没有人提到一个可能的问题,即电子邮件地址可以被视为私人地址。如果电子邮件地址是主键,那么配置文件页面URL很可能看起来像 ..../Users/my@email.com . 如果您不想公开用户的电子邮件地址怎么办?您必须找到其他方法来标识用户,可能是通过一个唯一的整数值来使URL类似 ..../Users/1 . 然后你最终会得到一个唯一的整数值。

        8
  •  8
  •   Rafa    12 年前

    logical level 电子邮件是自然的钥匙。 在 身体的 级别,如果您使用的是关系数据库,那么自然键与主键不匹配。原因主要是其他人提到的绩效问题。

    因此,可以对设计进行调整。自然的关键是 alternate key (唯一,不为空),并且使用 surrogate/artificial/technical key 作为主键,在您的情况下可以是自动增量。

    系统输出问题,

    如果有人想更改他的电子邮件地址怎么办?你也要换所有的外国钥匙吗?

    就是这样 cascading 是为了。

    使用数字代理键作为主键的另一个原因与索引在平台中的工作方式有关。例如,在MySQL的InnoDB中,表中的所有索引都预先挂起了主键,因此您希望pk尽可能小(以速度和大小为准)。同样与此相关的是,当主键按顺序存储时,InnoDB速度更快,而字符串在这方面没有帮助。

    另一个在使用字符串作为备用键时需要考虑的问题是,使用您想要的实际字符串的散列可能更快,跳过一些字母的大小写。(我实际上是在寻找证明我刚才所说的话的参考资料时降落在这里的;仍然在寻找…)

        9
  •  4
  •   ibram    14 年前

    是的,最好使用整数。您还可以将电子邮件列设置为唯一约束。

    这样地:

    CREATE TABLE myTable(
        id integer primary key,
        email text UNIQUE
    );
    
        10
  •  4
  •   Bryan Legend    14 年前

    是的,这是一个错误的主键,因为您的用户将要更新他们的电子邮件地址。

        11
  •  3
  •   klew    14 年前

    整数主键更好的另一个原因是当您在不同的表中引用电子邮件地址时。如果地址本身是主键,那么在另一个表中,必须将它用作键。所以你可以多次存储电子邮件地址。

        12
  •  3
  •   Community holdenweb    7 年前

    我对Postgres不太熟悉。主键是一个大主题。我在这个网站(stackoverflow.com)上看到了一些很好的问题和答案。

    我认为通过使用数字主键并在电子邮件列上使用唯一索引,您可能会获得更好的性能。电子邮件的长度往往会有所不同,可能不适用于主键索引。

    一些阅读 here here.

        13
  •  3
  •   tia    14 年前

    就个人而言,在设计数据库时,我不使用任何主键信息,因为很可能稍后需要更改任何信息。我提供主键的唯一原因是,从客户端执行大多数SQL操作很方便,我选择的是自动递增整数类型。

        14
  •  2
  •   jrharshath    14 年前

    您的同事是对的:使用一个自动递增的整数作为主键。

    您可以在应用程序级别实现电子邮件的唯一性,也可以将电子邮件地址列标记为唯一,并在该列上添加索引。

    将字段作为唯一字段添加将只在插入到该表时花费字符串比较,而不在执行联接和外键约束检查时花费。

    当然,您必须注意,在数据库级别向应用程序添加任何约束都可能导致应用程序变得不灵活。在将任何字段设置为“唯一”或“非空”之前,请务必适当考虑,因为您的应用程序需要它是唯一的或非空的。

        15
  •  2
  •   JoelFan    14 年前

    使用guid作为主键…这样,当您执行插入操作时,您就可以从程序中生成它,而不需要从服务器获得响应来了解主键是什么。它也将是唯一的交叉表和数据库,您不必担心如果有一天截断该表,并且自动增量被重置为1会发生什么。

        16
  •  2
  •   Robert    12 年前

    我知道这有点晚了,但我想补充一下,人们放弃了电子邮件帐户,服务提供商恢复了允许其他人使用的地址。

    正如@hlgem所指出的,“jsmith@somecompany.com一年后很容易归john smith所有,两年后又归julia smith所有。”在这种情况下,如果john smith想要您的服务,您要么拒绝使用他的电子邮件地址,要么删除所有与julia smith有关的记录。

    如果您必须删除记录,并且根据当地法律,这些记录与业务的财务历史有关,您可能会发现自己处于困境中。

    因此,我永远不会将电子邮件地址、号码牌等数据用作主键,因为无论这些数据有多独特,它们都超出您的控制范围,并且可以提供一些有趣的挑战,您可能没有时间来处理这些挑战。

        17
  •  1
  •   Display Name Camilo Terevinto    14 年前

    您可以使用整数主键来提高性能。

        18
  •  1
  •   oezi    14 年前

    您应该使用整数主键。如果您需要电子邮件列是唯一的,为什么不简单地在该列上设置一个唯一索引呢?

        19
  •  1
  •   Amareswar    14 年前

    如果您有一个非int值作为主键,那么插入和检索大型数据将非常缓慢。

        20
  •  1
  •   user2719152    9 年前

    主键应选择静态属性。由于电子邮件地址不是静态的,可以由多个候选人共享,因此使用它们作为主键不是一个好主意。此外,电子邮件地址通常是长度一定的字符串,其长度可能大于我们希望使用的唯一ID[len(email_address)>len(unique_id)],因此需要更多的空间,甚至最差的是,它们作为外键存储多次。从而导致性能下降。

        21
  •  1
  •   Stuart Parker    6 年前

    您可能需要考虑任何适用的数据法规。电子邮件是个人信息,例如,如果您的用户是欧盟公民,那么根据gdpr,他们可以指示您从您的记录中删除他们的信息(请记住,这适用于无论您所在的国家)。

    如果出于引用完整性或历史原因(如审核),需要将记录本身保存在数据库中,那么使用代理键将允许您仅空所有个人数据字段。如果他们的个人数据是主要的关键,这显然就不那么容易了。

        22
  •  0
  •   Lajos Arpad    14 年前

    这取决于桌子。如果表中的行代表电子邮件地址,那么电子邮件是最好的ID。如果不是,那么电子邮件不是一个好的ID。

        23
  •  0
  •   Micah    14 年前

    如果只是要求电子邮件是唯一的问题,那么您可以用该列创建一个唯一的索引。

        24
  •  0
  •   Chocolim    14 年前

    电子邮件是一个很好的唯一索引候选,但不适用于主键,例如,如果它是主键,您将无法更改联系人的电子邮件地址。 我认为你的加入查询也会变慢。

        25
  •  0
  •   Nikki    7 年前

    不要将电子邮件地址用作主键,保持电子邮件的唯一性,但不要将其用作主键,使用用户ID或用户名作为主键