【问题标题】:Is there a reason to have a separate id primary key if I already have an unique key?如果我已经有一个唯一键,是否有理由拥有一个单独的 id 主键?
【发布时间】:2016-11-04 06:33:28
【问题描述】:

假设我正在与 Steam 用户合作,每个用户都有一个独特的SteamID。我还需要一个单独的id 列作为主键,还是可以只使用 SteamID? IE。这够了吗(使用Flask-SQLAlchemy):

class User(db.Model):
    steamid = db.Column(db.String(20), primary_key=True, unique=True)
    name = db.Column(db.String(120))
    # more stuff

或者我是否仍应包含一个独特的 id,如 Flask-SQLAlchemy's examples 中所示:

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    steamid = db.Column(db.String(20), unique=True)
    name = db.Column(db.String(120))
    # more stuff

如果是这样,为什么

【问题讨论】:

  • 反对它的主要论据是性能,整数主键通常查询和使用更快。
  • 如果这真的是主要原因并且没有(真正的)功能差异,我不介意您将其发布为答案@FranciscoCouzo

标签: python sql database primary-key flask-sqlalchemy


【解决方案1】:

反对它的主要论据是性能,整数主键通常查询和使用更快。

这主要是一个偏好问题,如果按steamid 索引更有意义并且更容易推理,我会选择它,因为性能差异不会很大。

【讨论】:

    【解决方案2】:

    虽然 ID 值的数值确实可以更快地被系统排序和定位,但这种差异不太可能是明显的,甚至是无法测量的。

    问题是,您没有说明 steam 是什么或它在您的系统中扮演的角色。但是,显然,它与每个用户之间存在 1-1 的关系。那么为什么不在用户表中将其称为 ID 并根据需要将其别名为 UserIDSteamID 取决于在上下文中哪个更有意义用户恰好在那个时候。

    使用代理键时,我更喜欢将其称为 ID。简短、简单、明确。在查看表的定义时,它会说:“我是该表的代理键。”在同一个查询中使用多个表的相同字段时,确实没有混淆它。事实上,这有助于澄清:

    select User.ID, Item.ID, Entry.ID, etc.
    from ....
    

    但是,查询建立了结果集的上下文。别名有助于显示上下文:

    select User.ID as ManagerID, Item.ID OfficeOD, Entry.ID LaptopID, etc.
    from ....
    

    当在另一个表中将其用作 FK 时,该表中的名称也将显示它在该表建立的上下文中的用途。如果多个字段是同一个表的 FK,这将特别方便:

    table Accounts: 
      ID         the surrogate key to this table...duh!
      OwnerID    references User.ID
      AdminID    references User.ID
      VerifiedBy references User.ID
    

    或许

    table Accounts: 
      ID         the surrogate key to this table...duh!
      SteamID    references User.ID
      AdminID    references User.ID
      VerifiedBy references User.ID
    

    【讨论】:

    • 我想这会很好,但是如果它仍然做同样的事情,那么调用它idsteamid 有什么区别? “你没有说 Steam 是什么或它在你的系统中扮演的角色”哦,第一次提到 SteamID 实际上链接到 Valve 的页面,该页面完整地解释了 SteamID:developer.valvesoftware.com/wiki/SteamID
    • 没有阅读整个链接页面,但您的系统似乎在许多不同的上下文中保持相同的名称。这可能比更改名称以适应上下文更令人困惑。在表定义中看到“OwnerID”的开发人员也会在 FK 中看到它引用了 User 表并立即知道相关性。在引用 Accounts 表的不同表中定义“OwnerID”将阐明那个相关性。我已经编辑了答案以提供更多详细信息。
    【解决方案3】:

    在大多数情况下,SteamID 就足够了。如果 ID 很接近并且差异是 ID 中的空格或类似的东西,则可能会出现问题。使用 uniqueId 确实是最好的方法。

    【讨论】:

      猜你喜欢
      • 2016-11-15
      • 2012-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      • 2016-08-17
      • 2017-09-17
      • 1970-01-01
      相关资源
      最近更新 更多