【问题标题】:Create UserID even though usernames unique?即使用户名是唯一的,也要创建用户 ID?
【发布时间】:2012-07-24 19:24:47
【问题描述】:

我的 Web 应用程序将有各种类型的用户:root 用户、系统管理员、客户、承包商等。我想要一个包含“用户名”、“密码”列的“用户”表, 和“角色”,角色是上述角色之一。例如,我还会有一个名为“客户”的表来存储客户特定的属性。

这是我的问题。由于所有用户名都是唯一的,我可以使用用户名作为 User 表的主键。但是,创建一个“用户 ID”列并使用它而不是用户名列作为 PK 是否更有意义?还有许多其他表会将此用户 PK 用作外键,我认为从性能的角度来看,比较用户 ID 而不是用户名文本字符串会更快。

感谢您的回复。

【问题讨论】:

  • 虽然不用说,但无论您最终选择什么,都不要以明文形式存储密码。

标签: database database-design


【解决方案1】:

这是古老的自然键与替代键的争论。

简而言之,没有什么是一成不变的,您需要在相互竞争的利益之间取得平衡:

  1. 如果您预计需要更新密钥,请使用代理项(不需要更新)以避免 ON UPDATE CASCADE。
  2. 如果您需要查找键,而不是其他列,请使用自然键来完全避免 JOIN。但是,如果您需要查找的不仅仅是键,还可以使用代理来使 FK 和随附的索引更精简、更高效。
  3. 您是否预计自然键上的范围扫描?如果是,cluster 它。但是,二级索引在聚集表中的开销可能很大,这与代理键相对。
  4. 您的桌子很大吗?通过只有一个索引(在自然键上)而不是两个(在自然 代理上)来节省空间。
  5. correctly modeling diamond-shaped dependencies 可能需要复合自然键(位于标识关系的子端点)。
  6. 代理可能对 ORM 工具更友好。

如果是用户名...

  1. 您可能希望允许更新。
  2. 您不太可能需要查找用户名。
  3. 对用户名的范围扫描没有意义(与 equi-searches 不同)。
  4. 您没有存储地球上的全部人口,是吗?
  5. 我们在这里讨论的是“独立”自然键,而不是作为识别关系结果的自然键。
  6. 未知?

...所以在这种情况下,代理键可能是合理的。

【讨论】:

  • 谢谢,布兰科。你提出了一些我没有考虑过的有趣观点。我决定按照您和 HLGEM 的建议使用代理键。
【解决方案2】:

我会创建用户 ID,因为虽然用户名可能是唯一的,但它们通常不是不可更改的,而且我不希望更改数千或数百万条记录,因为 HLGEM 想成为 HLGEM_1。整数上的进一步连接更快。

【讨论】:

    【解决方案3】:

    有两种思想流派。数据库纯粹主义者认为,您应该始终尽可能使用自然键(这是有道理的)。因此,如果您订阅了该思路,并且用户名是不可更改的,则将密钥设为用户名。

    数据库实用主义者认为代理键更有用,并且往往能更好地适应需求的变化。在某些情况下,它们也可以更快,特别是对于大字符串键。还有安全问题,因为使用自然密钥可能会泄露代理密钥无法提供的信息。

    【讨论】:

      猜你喜欢
      • 2012-04-26
      • 1970-01-01
      • 2020-01-16
      • 1970-01-01
      • 2017-04-20
      • 2021-07-21
      • 2016-09-26
      • 2021-05-10
      • 1970-01-01
      相关资源
      最近更新 更多