订购数据库表中的列

时间:2010-01-21 22:48:01

标签: database database-design coding-style

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

这是我遵循的手工制作的惯例:

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

但是,这些问题仍未解决,所以我想听听你的想法。

4 个答案:

答案 0 :(得分:8)

简而言之,您已经很好地阐述了标准惯例,并且您没有错过很多。 IMO是唯一一个让人看起来不专业的举动,那就是首先没有主键。在那之后拥有外键是一个很好的约定,但不是什么大不了的事。 (包含外键的多字段主键当然应该处于开头阶段,否则应该被殴打。)我想补充两点:

  1. 具有相似主题的字段彼此靠近。例如,将City / State / Zip字段分开是没有用的。我认为,无论user_role还是user_ip都是第一位的,最轻微的并不重要,但它们听起来应该是彼此相邻的。
  2. 除了其他类似的惯例之外,对于按字母顺序排列的东西并没有什么坏处。
  3. 在数据库中添加其他约定 是一个非常好的主意(就像你提到的那样,最后总是有时间戳)。如果您在很多表中都有ChangeDate和ChangeBy字段,那么将它们(彼此相邻并且始终如一)放在一起就是好的。

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

    <强> 命名

    通常当你决定列顺序时,你决定列名,所以我想稍微解决一下。你可以通过字段的命名来制作可怕的,代价高昂的错误;这比列排序重要得多。订购可以很容易地改变,但糟糕的名字将永远导致你的问题。一年后更改表/列名称是十分痛苦的,因为有十几个引用它们。我刚刚添加了一个答案 here 来解决这个非常重要的话题。

答案 1 :(得分:6)

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

可以在Deciphering a SQL Server data page

处获得减少存储空间的尾随NULL的证明
  

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:-1)

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

  

始终保存CREATE TABLE语句,   以及所有其他陈述   在安全中定义数据库模式   地点。每次你做出改变   一个数据库对象,一定要   编写更改脚本并将其检入   版本控制软件,如   Visual Source Safe。

     

通过这样的政策,您可以轻松实现   在同一个上重新创建数据库模式   或者必要时使用不同的服务器。   此外,如果您有相同的数据库   多个服务器,很容易比较   模式并调和任何差异   随着时间的推移可能已经悄然而至。

     

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

     

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

     

创建常用的表格   相同的文件组。你可以期待   如果数据的性能好处   通常加入的表位于   相同的磁盘。

     

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

     

如果两个表有一个公共列,   例如customer_id,两者都有   表上有聚簇索引   customer_id列加入,等等   表格会更多   比加入相同的表更有效率   基于相同的列,但没有   聚集索引。

     

确保构建聚簇索引   包含不同

的列

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