【问题标题】:Ordering columns in database tables对数据库表中的列进行排序
【发布时间】:2013-01-28 20:40:57
【问题描述】:

对于数据库表中的列顺序,是否有任何标准或至少是最佳实践?

这是我遵循的手工约定:

  • 主键(即id);
  • 独特的列(即emailssn);
  • 外键(即article);
  • 保存用户生成数据的列(即first_namelast_name);
  • 保存系统生成数据的列;
    • 非布尔型(即password_hash);
    • 布尔值(即deletedverified
  • 时间戳列(即created_at);

不过,这些问题留下了许多未解决的问题,所以我想听听您的想法。

【问题讨论】:

  • 除了人类可读的组织之外,顺序在任何现代数据库中都不重要
  • 列名的最佳实践比订购恕我直言更重要。我将后缀“_PK”附加到我的主键和“_FK”到我的外键;从另一个数据库人那里学到了这个习惯。

标签: database database-design coding-style


【解决方案1】:

简而言之,您已经很好地说明了标准约定,并且您并没有错过很多。 IMO,唯一会让某人看起来不专业的举动是首先没有主键。在此之后立即使用外键是一个很好的约定,但没什么大不了的。 (包含外键的多字段主键当然应该在最开始,否则应该有人殴打。)我再补充两个想法:

  1. 具有相似主题的字段彼此靠近。例如,将 City/State/Zip 字段广泛分开是没有帮助的。我认为 user_role 或 user_ip 是否在前一点都没有关系,但它们听起来应该彼此相邻。
  2. 相对于其他此类约定,按字母顺序排列并没有什么坏处。

在你的数据库中有额外的约定是一个非常好的主意(就像你提到的总是在末尾有时间戳)。如果您的许多表格中都有 ChangeDate 和 ChangeBy 字段,那么让它们(显然彼此相邻并且)始终位于同一位置是很好的。

另外,ErikE 提到,在表的末尾使用可能经常包含空值的可变长度字段(varchar、nvarchar)可以提高效率。除此之外,我不认为在现代关系数据库中以某种方式安排事物有任何性能优势。

命名

通常,当您决定列顺序时,您也在决定列名,所以我想稍微解决一下这个问题。您当然会在字段的命名方面犯下可怕的、代价高昂的错误;这比您的列排序重要得多。订单可以轻松更改,但糟糕的名称会永远给您带来麻烦。一年后更改表/列名称是一个巨大的痛苦,因为有几十个对它们的引用。我刚刚添加了一个答案 here 来解决这个非常重要的话题。

【讨论】:

  • 我称我的表为“somethings”(复数),我的主键为“something”(单数)。
  • 是的,完美。客户.客户 ID。我与一个用 tbl 前缀标准数据表的人一起工作,并有一些其他前缀。做得好,我认为这还可以,但没有必要。
  • nouI verThink nouPrefixes verAre adjmuch adjWorse conThan nouNot adjNecessary。我认为他们草率并以有害的方式使数据库混乱。
  • 我喜欢你的答案随着时间的推移而演变。
【解决方案2】:

在 MSSQL Server 中,列列表末尾的 NULL 列实际上减少了存储该行所需的空间,这可以增加每页的行数,从而可以减少每次 I/O 操作所需的读取次数,这是一个性能优势。虽然性能优势可能不是很大,但对于任何具有大量 NULL 值的列,都需要牢记这一点。

可以在Deciphering a SQL Server data page 获得尾随 NULL 减少存储空间的证明:

...空位图略有不同 (fe / 1111 1110) 因为现在是 第二列为空。什么是 有趣的是,在这一行中,只有 单个可变长度列是 现在,不是两个。因此只有一个 单个可变长度列结束 索引标识符,0d00 / 0x000d / 13。 由此我们可以得出结论,列 按顺序处理,因此一个 可能要考虑的顺序 列,如果特定列是 通常为空,可能更多 最后订购的效率很高。

请注意,这仅适用于可变长度列。虽然这显然包括 varchar、varbinary 等,但我不确定其他数据类型(而且现在没有时间最终确定这一点)。

【讨论】:

    【解决方案3】:

    在 MS Sql Server 中,数据类型 ntext、image 和 text(最近都已弃用)应该是行中的最后一列以避免性能损失。

    【讨论】:

      【解决方案4】:

      您可以在网上找到不同的最佳实践。

      始终保存 CREATE TABLE 语句, 连同所有其他陈述 以安全的方式定义数据库模式 地点。每次你做出改变 到数据库对象,请务必 编写更改脚本并将其签入 版本控制软件,例如 视觉源安全。

      有了这样的政策,你可以轻松 在同一个上重新创建数据库模式 或其他服务器,如有必要。 另外,如果你有相同的数据库 多台服务器,很容易比较 架构并协调任何差异 这可能会随着时间的推移而蔓延。

      虽然是描述性的,但表名有 没有性能优势。他们做了 数据库自我记录和更容易 反对编码。表名应该 反映他们的商业意义。

      在非主数据库上创建用户表 文件组;保留主文件 系统对象的组。这种方式 系统提供和用户定义 对象不竞争磁盘 资源。

      在 相同的文件组。你可以期待 如果数据的性能优势 通常连接的表位于 同一个磁盘。

      在每个节点上创建一个聚集索引 桌子。每个表只能有一个 单个聚集索引。如果一个表有 一个聚集索引,它的数据是 根据物理排序 聚集索引键。聚集索引 在 SQL Server 中有许多好处。 例如,如果您从 使用 ORDER BY 子句的表 引用聚集索引键, 数据不需要排序 查询执行时间。

      如果两个表有一个共同的列, 例如 customer_id 和两者 表上有聚集索引 customer_id 列加入,如 桌子会多得多 比加入相同的表更有效 基于同一列但没有 聚集索引。

      确保聚集索引建立在 包含不同的列

      来源:Creating SQL Server tables: A best practices guide

      【讨论】:

      • 任何值得称道的数据库都会将现有模式输出为文本......至少 postgres、mysql、ms-sql 和 oracle 会这样做。
      • 对任何事情都推荐 Visual SourceSafe 投反对票,尤其是在 2010 年
      • @fuzzy lollipop:你推荐什么?我正在寻找与 SQL Server 数据库集成的东西(最好是管理工作室插件)
      • @fuzzy lollipp:我无意推荐 Visual SourceSafe。我使用它,我知道它的废话。
      • 您不需要与 SQL Server“集成”的东西。任何版本控制系统都可以工作,只是不要使用 Visual Source Safe,15 年来它是唯一一个我实际上丢失过无数次数据的版本控制系统。
      猜你喜欢
      • 2017-04-19
      • 1970-01-01
      • 1970-01-01
      • 2021-09-26
      • 2012-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-18
      相关资源
      最近更新 更多