【问题标题】:Thoughts on using email addresses as primary key [duplicate]关于使用电子邮件地址作为主键的想法[重复]
【发布时间】:2013-12-08 15:39:29
【问题描述】:

关于使用电子邮件地址作为主键的做法是什么?我应该避免它并使用自动递增的 ID 号,还是引擎也能够处理它?

MySQL 数据库,但我对其他引擎如何处理这个问题很感兴趣(特别是 PostgreSQL)。

【问题讨论】:

  • “作为数据库名称”到底是什么意思?为什么要将数据库命名为用户的电子邮件。听起来很奇怪的概念。或者您实际上是:意思是“使用电子邮件作为表格的主键
  • @a_horse_with_no_name 是的,我的意思是作为主键。更新了我的问题
  • 我喜欢这篇文章:database-programmer.blogspot.com/2008/01/…(我认为它回答了这个具体的问题,至于作者会选择什么)

标签: mysql database postgresql primary-key surrogate-key


【解决方案1】:

您应该始终拥有一个没有商业价值的唯一整数主键。然后将其称为代理键。

您应该将电子邮件地址本身存储在另一个字段中,通常带有索引,以便它可以充当查找的键。

这将使您能够提供基于使用电子邮件地址进行查找来定位用户的功能。那时的任何其他功能然后将记录主键用于其他操作,例如更新用户地址。

【讨论】:

  • 我认为“总是”有点太强了。有时会有一个简单、静态、小而明显的主键。只要您使用非常严格的密钥选择标准就可以了。使用电子邮件地址作为 PK 来识别用户在很多主要的关键选择标准上(最值得注意的是,他们改变了),所以在这种情况下,这确实是一个 可怕 的想法,并且没有好的替代自然密钥所以代理键在这里肯定是正确的选择。
【解决方案2】:

仅在满足一组相当狭窄的条件时才使用电子邮件地址是完全合理的:

  • 电子邮件地址是主要实体,它不识别其他内容(例如用户帐户)
  • 对表的 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 同意,另一些则不区分大小写。

是的。不要将它们用作 PK。

【讨论】:

    【解决方案3】:

    使用自动递增的主键。您无需向用户公开此信息,您可以直观地表示它,就好像关键是电子邮件地址一样,但您需要内部一致且不会随时间变化的数字。 p>

    请记住,您的主键用于链接到其他表,因此如果有人更改了他们的电子邮件地址,您还必须更新所有相关链接。这很难做到。

    无论您使用什么 SQL 数据库,它们的工作方式都大致相同,并且具有相似的限制。

    【讨论】:

    • 级联将消除[手动]“更新所有相关链接”的需要。 (现在,我同意不应将电子邮件用作 PK,但不是出于这个原因。)
    • 如果你依靠级联来保持这些东西的同步,你还有其他问题。这是一种锁定到单个数据库实例的设计,不会超出此范围。
    【解决方案4】:

    不使用业务信息作为主键而是使用代理主键的一个重要原因是外键。假设某人的电子邮件地址需要更新。你能想象更新密钥中的所有信息会是多么痛苦吗?如果您的外键足够严格,您可能最终不得不制作重复记录,更新所有子记录,然后删除原始记录。如果您使用代理主键(通常是自动生成的整数),这比简单地更新 1 条记录的电子邮件地址要难得多

    【讨论】:

    • 计数器:级联处理更新和电子邮件地址不经常更改。
    • @user2864740 你必须确保启用那些我通常不会这样做的级联约束。但这是更新的偏好——我当然不会通常在删除时这样做。从不使用业务数据作为主键的另一件事是,您通常会使用多列主键,这会使编程更加乏味——只需一列就容易得多——但这可能不会如果电子邮件仅存储在 1 列中的情况。我同意,在这种特殊情况下,它不是 100% 邪恶的,但它仍然与一般的良好做法背道而驰。
    • 我不同意这一点——只是断言数据库无法处理它。我认为电子邮件地址的 PK 效果不佳,因为它们在域中不必是唯一的(例如可以“共享”)并且可以随着时间的推移而重复(例如公司电子邮件);这不是由于数据库限制。
    • 我当然希望我没有给人留下数据库无法处理的印象。我只是说这样做是让数据库更难管理的一大组习惯的一部分。
    【解决方案5】:

    选择和设计密钥的合理标准是:简单、熟悉和稳定。电子邮件地址对于使用它们的人来说简单而熟悉,并且它们相对不经常更改。许多成功的网站和系统需要唯一的电子邮件地址来识别用户。电子邮件地址非常适合多种用途。

    鉴于电子邮件地址是一个合适的密钥,问题是它是否应该是一个 密钥。当一个表有多个键并且您希望出于某种目的选择其中一个作为“首选”时,就会出现主键的选择。关于什么应该或不应该成为主键的想法基本上是主观和任意的。没有可靠的理论基础可以做出这样的选择,因为指定为主键的键不需要在形式或功能上与任何其他键有任何不同。仅根据人类偏好,电子邮件地址应该比不熟悉且不相关的递增数字“更好”地选择主键。

    【讨论】:

    • 选择代理键(整数)而不是随时间变化的随机 varchar 有充分的理由。
    • 代理键值不是更“随机”(或至少如此随意以至于它也可能是随机的)吗?代理键值也会发生变化。如果没有适当的上下文来解释做出这种选择的目的,就没有绝对的基础。唯一可靠的答案是“这取决于……”
    • 电子邮件地址的稳定性下降,绝对不适合主键。他们改变。它们也不是特别具体 - 一个电子邮件地址可能由多个人(老人)使用,或者更常见的是,一个人可能有许多不同的电子邮件地址,他们希望关联。
    • 键可以并且确实会改变,这对于 any 键来说可能是正确的。多个人可能使用一个电子邮件地址这一事实与其作为密钥的适用性无关。四处看看。有大量网站和其他系统使用电子邮件地址来唯一标识用户帐户。
    猜你喜欢
    • 2011-04-17
    • 2020-08-12
    • 1970-01-01
    • 2018-05-30
    • 2010-11-04
    • 1970-01-01
    • 2021-08-29
    • 2015-11-19
    • 2019-12-17
    相关资源
    最近更新 更多