每当我设计数据库时,我总是想知道是否有命名数据库中项目的最佳方法。我经常问自己以下问题:

  1. 表名应该是复数吗?
  2. 列名应该是单数吗?
  3. 我应该为表或列添加前缀吗?
  4. 我应该在命名项目时使用大小写吗?

对于数据库中的项目命名,是否有任何推荐的指南?

有帮助吗?

解决方案

我建议查看 Microsoft 的 SQL Server 示例数据库:https://github.com/Microsoft/sql-server-samples/releases/tag/adventureworks

AdventureWorks 示例使用非常清晰且一致的命名约定,该约定使用架构名称来组织数据库对象。

  1. 表的单数名称
  2. 列的单数名称
  3. 表前缀的模式名称(例如:方案名称.表名称)
  4. 帕斯卡套管(又名大驼峰式小写)

其他提示

迟到的答案在这里,但简而言之:

  1. 我的 偏爱 是复数
  2. 是的
  3. 表格: :*通常*没有前缀是最好的。 : :不。
  4. 表和列:帕斯卡案例。

详细说明:

(1) 你必须做什么。 你能做的事情很少 必须 每次都以某种方式进行,但有几种。

  • 命名你的 主键 使用“[singularOfTableName]ID”格式。也就是你的表名是否是 顾客 或者 顾客, ,主键应该是 客户ID.
  • 更远, 外键 必须 命名一致 在不同的表中。殴打不这样做的人应该是合法的。我认为虽然定义的外键约束是 经常 重要的是,一致的外键命名是 总是 重要的
  • 你的数据库必须有 内部约定. 。尽管在后面的部分中你会看到我非常灵活, 之内 一个数据库的命名必须非常一致。您的顾客餐桌是否被称为 顾客 或者 顾客 比在同一个数据库中以相同的方式执行它更重要。你可以抛硬币来决定如何使用下划线,但随后你 必须继续以同样的方式使用它们. 。如果你不这样做,你就是一个应该低自尊的坏人。

(2) 你可能应该做什么。

  • 不同表中表示相同类型数据的字段 应该 被命名为相同。不要在一张桌子上有 Zip,而在另一张桌子上有 ZipCode。
  • 要分隔表名或列名中的单词,请使用 PascalCasing。使用驼峰命名法本质上不会有问题,但这不是惯例,而且看起来很有趣。稍后我将讨论下划线。(您不能像以前那样使用全部大写字母。20 年前,OBNOXIOUSTABLE.ANNOYING_COLUMN 在 DB2 中还可以,但现在不行了。)
  • 不要人为地缩短或缩写单词。名字长而清晰比短而混乱要好。超短名字是黑暗、野蛮时代的产物。Cus_AddRef。那到底是什么?保管收件人参考资料?客户额外退款?自定义地址推荐?

(3) 你应该考虑什么。

  • 我真的认为你应该为表使用复数名称;有些人认为单一。阅读其他地方的论点。但是,列名称应该是单数。即使您使用复数表名称,表示其他表组合的表也可能是单数。例如,如果您有一个 促销活动项目 表,表示促销活动一部分的项目的表可以是 Promotions_Items,但我认为它也可以合法地是 Promotion_Items(反映一对多关系)。
  • 出于特定目的一致使用下划线。使用 PascalCasing,一般表名称应该足够清晰;您不需要下划线来分隔单词。保存下划线(a)表示关联表或(b)表示前缀,我将在下一个项目符号中解决。
  • 前缀既不好也不坏。它 通常 不是最好的。在您的第一个或两个数据库中,我不建议使用前缀对表进行一般主题分组。表格最终无法轻松适合您的类别,但它实际上可以做到这一点 更难 寻找桌子。凭借经验,您可以规划并应用利大于弊的前缀方案。我曾经在数据库工作过,数据表以 表格, ,配置表 ctbl, 视图 看到, 过程的 sp, 和 udf 的 , ,以及其他一些;它经过精心、一致的应用,所以效果还不错。唯一需要前缀的时候是当您有真正独立的解决方案,并且由于某种原因驻留在同一个数据库中时;为它们添加前缀对于对表进行分组非常有帮助。对于特殊情况,例如您想要脱颖而出的临时表,前缀也是可以的。
  • 很少(如果有的话)您要前缀列。

好的,既然我们正在权衡意见:

我认为表名应该是复数。表是实体的集合(表)。每行代表一个实体,表代表集合。因此,我将把 Person 实体表称为 People(或 Person,无论您喜欢什么)。

对于那些喜欢在查询中看到单一“实体名称”的人,这就是我使用表别名的原因:

SELECT person.Name
FROM People person

有点像LINQ的“from person in people select person.Name”。

至于2、3和4,我同意@Lars。

我在一个拥有三名 DBA 的数据库支持团队工作,我们考虑的选项是:

  1. 任何命名标准都比没有标准好。
  2. 没有“唯一正确”的标准,我们都有自己的偏好
  3. 如果已有标准,请使用它。不要创建另一个标准或混淆现有标准。

我们对表使用单数名称。表往往以系统名称(或其缩写)作为前缀。如果系统复杂,这很有用,因为您可以更改前缀以将表按逻辑分组在一起(即reg_customer、reg_booking 和 regadmin_limits)。

对于字段,我们希望字段名称包含表的前缀/缩写(即cust_address1),我们也更喜欢使用一组标准后缀(_id 代表 PK,_cd 代表“代码”,_nm 代表“名称”,_nb 代表“数字”,_dt 代表“日期”)。

外键字段的名称应与主键字段的名称相同。

IE。

SELECT cust_nm, cust_add1, booking_dt
FROM reg_customer
INNER JOIN reg_booking
ON reg_customer.cust_id = reg_booking.cust_id

在开发新项目时,我建议您写出所有首选实体名称、前缀和首字母缩略词,并将此文档提供给您的开发人员。然后,当他们决定创建新表时,他们可以参考文档,而不是“猜测”表和字段应该被称为什么。

  1. 不。表应以其代表的实体命名。指的是其中一项记录所代表的人,而不是人。
  2. 再说一遍,同样的事情。FirstName 列确实不应该称为 FirstNames。这完全取决于您想用列表示什么。
  3. 不。
  4. 是的。为了清楚起见,将其案例化。如果您需要像“FirstName”这样的列,则使用大小写将使之更易于阅读。

好的。那是我的 0.02 美元

我也赞成 ISO/IEC 11179 风格的命名约定,并指出它们是指导方针而不是规定性的。

维基百科上的数据元素名称:

“表是实体的集合,并遵循集合命名准则。理想情况下,使用集体名称:例如,人员。复数也是正确的:雇员。不正确的名称包括:Employee、tblEmployee 和 EmployeeTable。”

与往常一样,规则也有例外,例如始终只有一行的表使用单一名称可能会更好,例如配置表。一致性至关重要:检查您的购物是否有约定,如果有,请遵守;如果你不喜欢它,那就做一个商业案例来改变它,而不是成为独行侠。

我们的偏好:

  1. 表名应该是复数吗?
    绝不。认为它是一个集合的论点是有道理的,但你永远不知道表将包含什么(0,1 或许多项目)。复数规则使命名变得不必要的复杂。一栋房子,两栋房子,老鼠对老鼠,人对人,我们甚至没有看过任何其他语言。

    Update person set property = 'value' 作用于表中的每个人。
    Select * from person where person.name = 'Greg' 返回人员行的集合/行集。

  2. 列名应该是单数吗?
    通常是的,除非你违反了规范化规则。

  3. 我应该为表或列添加前缀吗?
    主要是平台偏好。我们更喜欢在列前加上表名作为前缀。我们不为表添加前缀,但为视图 (v_) 和存储过程(sp_ 或 f_(函数))添加前缀。这可以帮助那些想要尝试更新 v_person.age 的人,它实际上是视图中的计算字段(无论如何都无法更新)。

    这也是避免关键字冲突的好方法(delivery.from 会中断,但 payment_from 不会)。

    它确实使代码更加冗长,但通常有助于提高可读性。

    bob = new person()
    bob.person_name = 'Bob'
    bob.person_dob = '1958-12-21'
    ...非常易读且明确。但这可能会失控:

    customer.customer_customer_type_id

    指示 customer 和 customer_type 表之间的关系,指示 customer_type 表 (customer_type_id) 上的主键,如果您在调试查询时看到“customer_customer_type_id”,您会立即知道它来自哪里(customer 表)。

    或者 customer_type 和 customer_category 之间存在 M-M 关系(仅某些类型可用于某些类别)

    customer_category_customer_type_id

    ...有点长(!)。

  4. 我应该在命名项目时使用大小写吗?是 - 小写:),带下划线。这些都是非常可读且跨平台的。结合上面3点也是有道理的。

    不过,其中大部分都是偏好。- 只要你的内容是一致的,那么对于任何必须阅读它的人来说都应该是可预测的。

我经常听到这样的争论:表是否复数完全取决于个人喜好,并且没有最佳实践。我不相信这是真的,尤其是作为一名程序员而不是 DBA。据我所知,除了“这对我来说有意义,因为它是对象的集合”之外,没有任何合理的理由将表名复数,而使用单数表名可以在代码中获得合法的收益。例如:

  1. 它避免了由复数歧义引起的错误和错误。程序员并不以其拼写专业知识而闻名,并且某些单词的复数形式令人困惑。例如,复数单词是以“es”结尾还是仅以“s”结尾?是人还是人?当您与大型团队一起处理项目时,这可能会成为一个问题。例如,团队成员使用不正确的方法对其创建的表进行复数化的实例。当我与该表交互时,它已在我无法访问或需要很长时间才能修复的代码中使用。结果是我每次使用该表时都必须记住将其拼写错误。与此非常相似的事情发生在我身上。您越能让团队的每个成员一致、轻松地使用准确、正确的表名称,而不会出现错误,也不必一直查找表名称,那就越好。单一版本在团队环境中更容易处理。

  2. 如果您使用表名的单数版本,并在主键前添加表名前缀,那么您现在可以轻松地通过代码从主键确定表名,反之亦然。您可以得到一个带有表名的变量,将“Id”连接到末尾,现在您可以通过代码获得表的主键,而无需执行额外的查询。或者,您可以从主键末尾截去“Id”,以通过代码确定表名。如果您使用“id”而没有主键的表名称,则无法通过代码从主键确定表名称。此外,大多数使用复数表名并在 PK 列前加上表名的人在 PK 中使用表名的单数版本(例如 statuses 和 statusId),这根本不可能做到这一点。

  3. 如果将表名设置为单数,则可以让它们与它们代表的类名相匹配。再一次,这可以简化代码并允许您做一些非常巧妙的事情,例如只用表名来实例化一个类。它还只会使您的代码更加一致,从而导致......

  4. 如果您将表名称设置为单数,则可以使您的命名方案在每个位置都一致、有组织且易于维护。您知道,在代码中的每个实例中,无论是在列名称中、作为类名称还是作为表名称,它都是完全相同的名称。这使您可以进行全局搜索以查看使用数据的所有位置。当您使用复数形式的表名称时,有时您将使用该表名称的单数版本(它在主键中变成的类)。在某些情况下,您的数据被称为复数,而在某些情况下被称为单数,这是有道理的。

总而言之,如果您使用复数形式的表名称,您将失去使代码更智能、更易于处理的各种优势。甚至在某些情况下,您必须使用查找表/数组将表名转换为您可以避免的对象或本地代码名称。单一表名虽然一开始可能感觉有点奇怪,但与复数名称相比具有显着的优势,我相信这是最佳实践。

看看 ISO 11179-5:命名和标识原则您可以在这里获得: http://metadata-standards.org/11179/#11179-5

我不久前在博客上谈到过它: ISO-11179 命名约定

我知道这已经晚了,而且这个问题已经得到了很好的回答,但我想就列名前缀的#3 提出我的意见。

所有列都应使用定义它们的表唯一的前缀来命名。

例如。给定表“customer”和“address”,我们分别使用前缀“cust”和“addr”。“客户”将具有“cust_id”、“cust_name”等。在里面。“地址”将具有“addr_id”、“addr_cust_id”(FK 返回给客户)、“addr_street”等。在里面。

当我第一次看到这个标准时,我坚决反对它。我讨厌这个主意。我无法忍受所有额外的打字和冗余的想法。现在我已经有了足够的经验,我再也不会回去了。

这样做的结果是数据库模式中的所有列都是唯一的。这样做有一个主要好处,它胜过了所有反对它的论点(当然,在我看来):

您可以搜索整个代码库并可靠地找到涉及特定列的每一行代码。

#1 的好处是非常巨大的。我可以弃用某个列,并确切地知道需要更新哪些文件,然后才能安全地从架构中删除该列。我可以更改列的含义并确切地知道哪些代码需要重构。或者我可以简单地判断列中的数据是否正在系统的特定部分中使用。我无法计算有多少次这将一个潜在的庞大项目变成了一个简单的项目,也无法计算我们在开发工作中节省了多少时间。

另一个相对较小的好处是,在进行自连接时只需使用表别名:

SELECT cust_id, cust_name, addr_street, addr_city, addr_state
    FROM customer
        INNER JOIN address ON addr_cust_id = cust_id
    WHERE cust_name LIKE 'J%';

对于这些我的看法是:

1)不,表名应该是单数。

虽然对于简单的选择来说似乎是有意义的(select * from Orders)对于 OO 等价物来说意义不大(Orders x = new Orders).

数据库中的表实际上是该实体的集合,一旦您使用集合逻辑,它就更有意义:

select Orders.*
from Orders inner join Products
    on Orders.Key = Products.Key

最后一行,即连接的实际逻辑,看起来与复数表名称混淆。

我不确定总是使用别名(正如马特建议的那样)可以解决这个问题。

2) 他们应该是单数,因为他们只拥有 1 项财产

3)永远不要,如果列名不明确(如上所述,它们都有一个名为 [Key] 的列),表的名称(或其别名)可以很好地区分它们。您希望查询能够快速输入且简单 - 前缀会增加不必要的复杂性。

4)无论你想要什么,我建议使用大写字母

我认为对于其中任何一个都没有一套绝对的指导方针。

只要您选择的内容在应用程序或数据库中保持一致,我认为这并不重要。

在我看来:

  1. 表名应该是复数。
  2. 列名应该是单数。
  3. 不。
  4. 表名和列名均采用驼峰命名法(我的首选)或下划线分隔符。

然而,正如已经提到的,任何约定都比没有约定好。无论您选择如何执行,都将其记录下来,以便将来的修改遵循相同的约定。

  1. 绝对保持表名单数,是人而不是人
    1. 同样在这里
    2. 不。我见过一些可怕的前缀,甚至说明我们正在处理的是表(tbl_)或用户存储过程(usp_)。接下来是数据库名称...不要这样做!
    3. 是的。我倾向于将所有表名都采用 PascalCase

我认为这些问题的最佳答案将由您和您的团队给出。拥有一个命名约定比命名约定的精确程度要重要得多。

由于没有正确的答案,您应该花一些时间(但不要太多)并选择您自己的约定 - 这是 重要的部分——坚持下去。

当然,最好寻求一些有关标准的信息,这就是您所要求的,但不要担心或担心您可能得到的不同答案的数量:选择最适合您的一个。

以防万一,我的回答如下:

  1. 是的。一个表是一组 记录, 教师 或者 演员, , 所以...复数。
  2. 是的。
  3. 我不使用它们。
  4. 我更经常使用的数据库 - Firebird - 将所有内容保留为大写,所以这并不重要。无论如何,当我编程时,我会以更容易阅读的方式编写名称,例如 发布年份.

命名约定允许开发团队在项目的核心设计可发现性和可维护性。

良好的命名约定需要时间来发展,但一旦到位,团队就可以使用共同语言继续前进。良好的命名约定会随着项目的发展而有机地发展。良好的命名约定可以轻松应对软件生命周期中最长且最重要的阶段(生产中的服务管理)期间的变化。

以下是我的回答:

  1. 是的,当表名引用一组数据时,表名应该是复数。 交易, 证券, , 或者 交易对手 例如。
  2. 是的。
  3. 是的。SQL 表以 tb_ 为前缀,视图以 vw_ 为前缀,存储过程以 usp_ 为前缀,触发器以 tg_ 为前缀,后跟数据库名称。
  4. 列名称应为小写,并用下划线分隔。

命名很困难,但在每个组织中都有一个人可以命名事物,并且在每个软件团队中都应该有一个人负责命名标准并确保诸如此类的命名问题 秒号, 秒值安全 ID 在它们融入项目之前尽早解决。

那么良好的命名约定和标准的基本原则是什么:-

  • 使用客户的语言和解决方案域
  • 具有描述性
  • 始终如一
  • 消除歧义、反思和重构
  • 除非所有人都清楚,否则不要使用缩写
  • 不要使用SQL保留的关键字作为列名称

这是提供一些选择的链接。我正在寻找一个可以遵循的简单规范,而不必依赖于部分定义的规范。

http://justinsomnia.org/writings/naming_conventions.html

表名应始终是单数,因为它们代表一组对象。正如你所说的“牧群”是指一群羊,“羊群”是指一群鸟。不需要复数。当表名由两个名称组成并且命名约定为复数时,很难知道复数名称应该是第一个单词还是第二个单词还是两者。这是逻辑——Object.instance,而不是objects.instance。或 TableName.column,而不是 TableNames.column。Microsoft SQL 不区分大小写,当表名或列名由两个或多个名称组成时,如果使用大写字母,则更容易读取表名或列名。

SELECT 
   UserID, FirstName, MiddleInitial, LastName
FROM Users
ORDER BY LastName

表名: 它应该是单一的,因为它是代表现实世界对象的单一实体,而不是单一的对象。

栏目名称: 它应该是奇异的,只有这样它才表明它将拥有原子值并符合归一化理论。但是,如果有 n 个相同类型的属性,则它们应以 1、2、...、n 等为后缀。

为表/列添加前缀:这是一个很大的话题,稍后再讨论。

套管:应该是驼峰案例

我的朋友, 帕特里克·凯彻, ,我请求您不要写任何可能冒犯某人的内容,如您所写,“•此外,外键在不同表中的命名必须一致。殴打不这样做的人应该是合法的。”我的朋友帕特里克我从来没有犯过这个错误,但我写得一般。如果他们一起计划为此击败你怎么办?:)

聚会已经很晚了,但我仍然想添加关于列前缀的两分钱

使用 table_column (或 tableColumn)列命名标准似乎有两个主要论据,两者都基于列名本身在整个数据库中是唯一的这一事实:

1)您不必始终在查询中指定表名和/或列别名

2)您可以轻松地在整个代码中搜索列名称

我认为这两种论点都有缺陷。不使用前缀解决这两个问题的方法很简单。这是我的建议:

始终在 SQL 中使用表名。例如,始终使用 table.column 而不是 column。

它显然解决了 2),因为您现在只需搜索 table.column 而不是 table_column。

但我能听到你尖叫,这怎么解决1)?这正是为了避免这种情况。是的,确实如此,但该解决方案存在严重缺陷。为什么?好吧,前缀解决方案归结为:
为了避免在出现歧义时必须指定 table.column,您将所有列命名为 table_column!
但这意味着从现在起您每次指定列时都必须写入列名。但如果你无论如何都必须这样做,那么与总是显式编写 table.column 相比,有什么好处呢?确切地说,没有任何好处,输入的字符数完全相同。

编辑:是的,我知道用前缀命名列会强制正确使用,而我的方法依赖于程序员

基本数据库命名约定(和风格) (点击此处查看更详细的说明)

表名名称选择简短的,明确的名称,使用不超过一个或两个单词来区分表很容易促进唯一字段名称的命名以及查找和链接表格给表格单数,从不复数(更新:更新:我仍然同意这个约定的原因,但大多数人真的喜欢复数表名,所以我软化了我的立场)...请点击上面的链接

表名单数。假设您正在对某人与其地址之间的关系进行建模。例如,如果您正在阅读DataModel,您希望“每个人都可以住在0,1或许多地址”。或“每个人都可以生活在0,1或许多地址”。我认为它更容易复合地址,而不是必须重新以人为单位的人。另外,集体名词通常与单数名词不同。


--Example SQL

CREATE TABLE D001_Students
(
    StudentID INTEGER CONSTRAINT nnD001_STID NOT NULL,
    ChristianName NVARCHAR(255) CONSTRAINT nnD001_CHNA NOT NULL,
    Surname NVARCHAR(255) CONSTRAINT nnD001_SURN NOT NULL,
    CONSTRAINT pkD001 PRIMARY KEY(StudentID)
);

CREATE INDEX idxD001_STID on D001_Students;

CREATE TABLE D002_Classes
(
    ClassID INTEGER CONSTRAINT nnD002_CLID NOT NULL,
    StudentID INTEGER CONSTRAINT nnD002_STID NOT NULL,
    ClassName NVARCHAR(255) CONSTRAINT nnD002_CLNA NOT NULL,
    CONSTRAINT pkD001 PRIMARY KEY(ClassID, StudentID),
    CONSTRAINT fkD001_STID FOREIGN KEY(StudentID) 
        REFERENCES D001_Students(StudentID)
);

CREATE INDEX idxD002_CLID on D002_Classes;

CREATE VIEW V001_StudentClasses
(
    SELECT
        D001.ChristianName,
        D001.Surname,
        D002.ClassName
    FROM
        D001_Students D001
            INNER JOIN
        D002_Classes D002
            ON
        D001.StudentID = D002.StudentID
);

这些是我学到的约定,但您应该适应您开发软管使用的任何内容。

  1. 复数。它是实体的集合。
  2. 是的。属性是实体的单一属性的表示。
  3. 是的,前缀表名允许轻松跟踪所有约束索引和表别名的命名。
  4. 表名和列名采用帕斯卡大小写,索引和约束采用前缀 + 全部大写。
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top