【问题标题】:MySQL naming conventions, should field name include the table name?MySQL命名约定,字段名是否应该包含表名?
【发布时间】:2010-11-22 00:59:55
【问题描述】:

朋友告诉我,同一张表的字段名中应该包含表名,不知道为什么?它应该是这样的吗? 示例:

(Table) Users  
(Fields) user_id, username, password, last_login_time

我发现前缀 'user_' 没有意义,因为我知道它已经是给用户的了。但我也想听听你的意见。 注意:我正在用 php、mysql 编程。

【问题讨论】:

  • 我正在使用 Doctrine-Project(一个 ORM 框架),它的用法是这样的:one(User)-to-one(Picture): User[id, name, age, picture_id],图片[id, 文件名, 文件]

标签: php mysql database naming-conventions


【解决方案1】:

对于像“id”和“name”这样的通用字段,最好把表名放进去。

原因是在编写跨多个表的联接时可能会造成混淆。

这是个人喜好,真的,但这就是背后的原因(我总是这样做)。

无论您选择哪种方法,请确保它在项目中保持一致。

【讨论】:

    【解决方案2】:

    我同意你的看法。我很想将表名或其缩写形式放在主键和外键上,或者如果“自然”名称是关键字。

    Users: id or user_id, username, password, last_login_time
    Post: id or post_id, user_id, post_date, content
    

    我通常使用 'id' 作为主键字段名称,但在这种情况下,我认为 user_id 和 post_id 也完全可以。请注意,发布日期称为“post_date”,因为“日期”是关键字。

    至少这是我的约定。您的里程可能会有所不同。

    【讨论】:

    • 在主键和外键上使用 user_id 而不是 id 的一个优点是它使 NATURAL 连接变得轻而易举。
    【解决方案3】:

    我认为没有理由包含表名,这是多余的。在查询中,您可以将字段称为

    .(例如“user.id”)。

    【讨论】:

    • @Omar Dolaimy:你的“非常新”与这个答案无关。考虑删除您的评论。
    【解决方案4】:

    在列名前加上表名是保证列名唯一的一种方式,这使得连接更容易。

    但这是一种令人厌烦的做法,尤其是当我们的表名很长时。在适当的时候使用别名通常更容易。此外,当我们自加入时,它也无济于事。

    作为一名数据建模师,我确实发现很难始终保持一致。对于 ID 列,我理论上更喜欢只有 ID,但我通常会发现我的表中的列名为 USER_IDORDER_ID 等。

    在某些情况下,跨多个表使用公共列名可能会带来积极的好处。例如,当逻辑超类型/子类型关系仅呈现为子表时,保留所有子类型表(例如ITEM_STATUS)上的超类型列而不是重命名它是有用的每个子类型(ORDER_ITEM_STATUSINVOICE_ITEM_STATUS 等)。当它们是具有一组通用值的枚举时尤其如此。

    【讨论】:

      【解决方案5】:

      我个人不会为主表中的字段名添加表名,但是当将其用作另一个表中的外部字段时,我会在它前面加上源表的名称。例如users 表上的 id 字段将称为 id,但在 cmets 表上,cmets 链接到发布它们的用户,它将是 user_id。

      这是我从 CakePHP 的命名方案中挑选出来的,我认为它非常简洁。

      【讨论】:

      • 这很常见(我遵循这种做法)。有趣的是,它也是一个反对列名中的表名的论据——或者至少与这样做不兼容,因为命名方案乍一看会让人感到困惑。
      【解决方案6】:

      例如,您的数据库中有存储有关销售和人力资源部门信息的表,您可以将所有与销售部门相关的表命名如下:

      SL_NewLeads SL_Territories SL_TerritoriesManagers

      您可以将所有与人力资源部门相关的表命名如下:

      HR_Candidates HR_PremierInstitutes HR_面试时间表

      这种命名约定确保当您按字母顺序列出所有表时,所有相关表都被组合在一起。但是,如果您的数据库只处理一组逻辑表,则无需使用此命名约定。

      请注意,有时您最终会将表垂直分区为两个或多个表,尽管这些分区实际上表示同一个实体。在这种情况下,在实体名称中附加一个最能识别分区的词

      【讨论】:

        【解决方案7】:

        听起来结论是: 如果字段名称在表中是唯一的 - 以表名作为前缀。如果字段名称有可能在其他表中重复,请将其命名为唯一。

        我找到了诸如“img、地址、电话、年份”之类的字段名称,因为不同的表格可能包含不同的图像、地址、电话号码和年份。

        【讨论】:

          【解决方案8】:

          实际上,这种命名是有原因的,尤其是在涉及领域时,您可能会加入。至少在 MySQL 中,您可以使用 USING 关键字而不是 ON,然后 users u JOIN posts p ON p.user_id = u.id 变为 users u JOIN posts p USING(user_id),这是更干净的 IMO。

          关于其他类型的字段,您可能会在选择* 时受益,因为您不必指定您需要的字段列表并确定哪个字段来自哪个表。但通常出于性能和维护原因不鼓励使用 SELECT *,因此我认为在此类字段前加上表名前缀是一种不好的做法,尽管它可能因应用程序而异。

          【讨论】:

          • 同意,前提是您唯一的用例是手写 sql。 SQL 包装器和/或 ORM 解决方案将具有 foo.id 和相关表 fkey 作为 bar.fooID。我正在将一个手动编码的数据库(完全 o' clean JOIN .. USING ..)迁移到 ScalaQuery。如果需要下拉到手动 SQL,语句现在将采用 SELECT baz FROM foo f JOIN bar b ON f.id = b.fooID 的形式。当然不是那么干净,但是运行 MySQL 和 Jedis 以及像 SQ 这样的功能性 SQL 包装器意味着强类型查询没有像 Hibernate 这样的完整 ORM 的开销。快速有趣,搭乘 TypeSafe 列车 ;-)
          • 实际上,经过进一步思考,这个回复得到了我的 +1。你可以吃蛋糕也可以吃。创建域特定的 pkeys & fkeys a la userID, orderID。这允许在需要下拉到手动 sql 时进行语义上有意义的字段选择(例如 alias.fooID 与 alias.id 作为 fooID)和干净的自然连接。然后,在 wrapper/ORM 层只需使用 domain.id 约定,因为无论如何您都在使用对象(即没有意义写 foo.fooID,只需说 foo.id)
          【解决方案9】:

          我们应该用表名前缀来定义主键。

          如果 id 和 post_id 而不是 id,我们应该使用 use_id 代替。

          好处:-

          1) 易于阅读

          2) 在连接查询中轻松区分。我们可以在查询中尽量减少别名的使用。

          用户表:user_id(PK)

          post 表:post_id(PK) user_id(FK) 这里用户表 PK 和 post 表 FK 相同

          根据documentation

          3) 这样我们就可以获得NATURAL JOIN和JOIN with USING的好处

          自然连接和使用 USING 的连接,包括外连接变体,是 按照 SQL:2003 标准处理。目标是对齐 MySQL 关于 NATURAL JOIN 的语法和语义和 JOIN ... 根据 SQL:2003 使用。然而,这些变化在加入 处理可能会导致某些连接的输出列不同。 此外,一些在旧版本中似乎可以正常工作的查询 (5.0.12 之前)必须重写以符合标准。

          这些变化有五个主要方面:

          1) MySQL 确定 NATURAL 或 USING 连接操作的结果列的方式(以及整个 FROM 子句的结果)。

          2) 将 SELECT * 和 SELECT tbl_name.* 扩展为选定列的列表。

          3) NATURAL 或 USING 连接中的列名解析。

          4) 将 NATURAL 或 USING 连接转换为 JOIN ... ON。

          5) 在 JOIN ... ON 的 ON 条件下解析列名。

          例子:-

          SELECT * FROM user NATURAL LEFT JOIN post;
          SELECT * FROM user NATURAL JOIN post;
          SELECT * FROM user JOIN post USING (user_id);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-02-07
            • 1970-01-01
            • 2013-12-31
            • 2011-04-25
            相关资源
            最近更新 更多