提问



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



  1. 表格名称应该是复数吗?

  2. 列名应该是单数吗?

  3. 我应该为表格或列添加前缀吗?

  4. 我是否应该在命名项目中使用任何案例?



是否有任何建议的指南用于命名数据​​库中的项目?

最佳参考


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


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



  1. 表格的奇异名称

  2. 列的奇异名称

  3. 表格的模式名称前缀(例如:SchemeName.TableName)

  4. 帕斯卡尔外壳(a.k.a。上骆驼箱)


其它参考1


这里的答案很晚,但简而言之:



  1. 我的偏好是复数


  2. 表:*通常*没有前缀是最好的。 列:否。

  3. 表和列:PascalCase。



阐述:


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



  • 使用[[singularOfTableName]] ID格式命名主键。也就是说,无论您的表名是 Customer 还是 Customers ,主键都应该是 CustomerID 。

  • 此外,外键必须在不同的表中一致地命名。殴打不这样做的人应该是合法的。我会提交,虽然定义的外键约束经常重要,但一致的外键命名总是重要

  • 您的数据库必须具有内部约定。即使在后面的部分中,您会发现我非常灵活,在中,数据库命名必须非常一致。无论您的客户表是 Customers 还是 Customer, 不如在同一个数据库中以相同的方式执行它。并且您可以翻转硬币以确定如何使用下划线,但是必须以相同的方式继续使用它们如果你不这样做,你就是一个自尊心低的坏人。



(2) 你应该做什么。



  • 表示不同表上相同类型数据的字段应命名相同。不要在一张桌子上放Zip,在另一张桌子上放ZipCode。

  • 要分隔表名或列名中的单词,请使用PascalCasing。使用camelCasing本质上不会有问题,但这不是惯例,它看起来很有趣。我会在一瞬间解决下划线问题。 (你可能不会像过去那样使用ALLCAPS.OBNOXIOUSTABLE.ANNOYING_COLUMN在20年前在DB2中没问题,但现在还没有。)

  • 唐t。不要人为地缩短或缩写词,是比短和混乱的长和明确的名称更好。超短的名字是从黑暗,更野蛮时代缓缴。Cus_AddRef。这到底是什么呢?保管收件人参考?客户额外退款?自定义地址推荐?



(3) 你应该考虑什么。



  • 我真的认为你应该有多个表名;有些人认为是单数。阅读别处的论点。但是列名应该是单数。即使您使用多个表名,表示其他表组合的表也可能是单数。例如,如果您有促销和项表,则表示作为促销一部分的商品的表可以是Promotions_Items,但它也可以合法地为Promotion_Items I思考(反映一对多的关系)。

  • 始终如一地使用下划线并用于特定目的。只有通用表名称应该与PascalCasing足够清楚;你不需要下划线来分隔单词。保存下划线(a)表示关联表或(b)表示前缀,我将在下一个子弹中说明。

  • 前缀既不好也不坏。 通常并不是最好的。在你的第一个数据库中,我不会建议使用前缀来进行表的一般主题分组。表最终不能轻松地适合您的类别,实际上它可以让更难来查找表。根据经验,您可以计划和应用比损害更有益的前缀方案。我在数据表开始时使用 tbl ,使用 ctbl 创建配置表,使用 vew 查看视图,使用proc sp ,和udfs fn 等等;它是一丝不苟,一贯应用,所以它很好。您需要前缀的唯一时间是您有真正独立的解决方案,由于某种原因,它们位于同一个数据库中;为它们添加前缀对于对表进行分组非常有帮助。对于特殊情况,前缀也是可以的,例如您想要突出的临时表。

  • 你想要的很少(如果有的话)
    为列添加前缀。


其它参考2


好的,既然我们正在考虑意见:


我认为表名应该是复数。表是实体的集合(表)。每行代表一个实体,表代表集合。因此,我会将一个人物实体人员(或人员,无论你喜欢什么)称为表格。


对于那些喜欢在查询中看到单个实体名称的人来说,那就是我将使用表别名:


SELECT person.Name
FROM People person


有点像LINQs来自人们选人。名称。


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

其它参考3


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



  1. 任何命名标准都优于无标准。

  2. 没有一个真实的标准,我们都有自己的偏好

  3. 如果已经有标准,请使用它。不要制定另一个标准或使现有标准变得混乱。



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


对于场我们D预期的字段名称是包含表的前缀/acryonm(即cust_address1),我们也喜欢使用一套标准的后缀(_id对于PK的,_CD为‘代码’,为_nm名称,_nb代表数字,_dt代表日期)。


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





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


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

其它参考4



  1. 否。表应该以它所代表的实体命名。
    人,而不是人是你如何指代其中一个记录所代表的人。

  2. 同样的事情。 FirstName列确实不应该被称为FirstNames。这一切都取决于你想用列表示什么。

  3. NO。

  4. 是。为了清楚起见。如果你需要像FirstName这样的列,套管将使它更容易阅读。



好。这是我的0.02美元

其它参考5


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


请参阅维基百科上的数据元素名称:[17]


表是实体集合,并按照集合命名指南理想情况下,一个集体名称用于:。例如,人事复数也是正确的:员工不正确的名称包括:。员工,tblEmployee和EmployeeTable中


与往常一样,规则有例外,例如一个总是只有一行的表可能更好用一个单一的名称,例如配置表。一致性至关重要:检查你的商店是否有约定,如果是,请遵循它;如果你不喜欢它,那么做一个商业案例让它改变而不是孤独的游侠。

其它参考6


我们的偏好:



  1. 表名应该是复数?

    决不。它作为集合的参数是有意义的,但你永远不知道该表将包含什么(0,1或许多项)。多个规则使得命名不必要地复杂化。 1房子,2个房子,老鼠与老鼠,人与人,我们甚至没有看过任何其他语言。


    Update person set property = 'value'对表中的每个人采取行动
    Select * from person where person.name = 'Greg'返回人行的集合/行集。

  2. 列名是否应该是单数?

    通常,是的,除非您违反规范化规则。

  3. 我应该为表格或列添加前缀吗?

    主要是平台偏好。我们更喜欢使用表名为列添加前缀。我们没有前缀表,但我们做前缀视图(v_)和stored_procedures(sp_或f_(函数))。这有助于想要尝试更新v_person.age的人,这实际上是视图中的计算字段(可以无论如何都要更新。


    这也是避免关键字冲突的好方法(delivery.from break,但delivery_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_type和customer_category之间存在M-M关系(某些类别只能使用某些类型)


    customer_category_customer_type_id


    ...在长边上有点(!)。

  4. 我应该在命名项目中使用任何案例吗?
    是的 - 小写:),带下划线。这些是非常易读和跨平台的。加上3以上它也是有道理的。


    其中大部分都是偏好。 - 只要你保持一致,任何必须阅读它的人都应该可以预测。


其它参考7


请参阅ISO 11179-5:命名和识别原则
你可以在这里得到它:http://metadata-standards.org/11179/#11179-5 [18]


我在这里写了一段时间的博客:ISO-11179命名约定[19]

其它参考8


我一直听到这样的论点,即一张桌子是否多元化都是个人品味的问题而且没有最佳实践。我不相信这是真的,尤其是作为程序员而不是DBA。据我所知,没有合理的理由来复制表名而不是它对我有意义,因为它是一个集合对象,虽然通过使用单个表名来获得合法的代码收益。例如:



  1. 它避免了由多个含糊不清引起的错误和错误。程序员并不完全以他们的拼写专业知识而闻名,而且复数一些单词令人困惑。例如,复数单词是以es还是s结尾?是人还是人?当你从事大型项目时团队,这可能成为一个问题。例如,一个团队成员使用不正确的方法来复数他创建的表的实例。当我与这个表交互时,它在代码中被全部使用我无法访问或需要很长时间才能修复。结果是我必须记住每次使用它时拼错表。与此非常相似的事情发生在我身上。您可以更轻松地让团队中的每个成员始终如一地轻松地使用准确,正确的表名而不会出现错误,或者必须始终查找表名,这样做会更好。单一版本在团队环境中更容易处理。

  2. 如果您使用表名的单数形式并使用表名前缀主键,则现在可以通过单独的代码轻松地从主键确定表名,反之亦然。您可以为其指定一个带有表名的变量,将Id连接到末尾,现在您可以通过代码获得表的主键,而无需执行其他查询。或者,您可以从主键的末尾切断Id,以通过代码确定表名。如果对主键使用没有表名的id,则无法通过代码从主键确定表名。此外,大多数使用表名复用表名和前缀PK列的人使用PK中表名的单数形式(例如status和statusId),这使得根本不可能这样做。

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

  4. 如果您使表名称为单数,则会使您的命名方案在每个位置都保持一致,有条理且易于维护。您知道在代码中的每个实例中,无论是在列名中,作为类名还是作为表名,它都是相同的名称。这允许您进行全局搜索以查看使用数据的所有位置。当您复数表名时,将会出现您将使用该表名的单数版本(它在主键中转换为的类)的情况。没有一些实例,你的数据被称为复数,有些实例是单数的,这是有道理的。



总结一下,如果你复数表名,那么你就会失去各种优势,使你的代码变得更聪明,更容易处理。甚至可能存在必须使用查找表/数组将表名转换为可避免的对象或本地代码名称的情况。奇异的表名虽然起初可能有些奇怪,但与多元名称相比具有明显的优势,我相信这是最佳实践。

其它参考9


我知道这已经很晚了,这个问题已经得到了很好的回答,但是我想对#3关于列名前缀的看法。


所有列都应使用对其定义的表唯一的前缀命名。


例如。给定表customer和address,让我们分别使用cust和addr的前缀。customer将包含cust_id,cust_name等。address会有其中包含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%';

其它参考10


我对这些的看法是:


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


虽然它似乎对简单的选择(select * from Orders有意义,但对于OO等价物(Orders x = new Orders)则没有意义。


DB中的表实际上是该实体的集合,一旦您使用set-logic,它就更有意义:


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


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


我不确定总是使用别名(如Matt建议的那样)清除它。


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


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


4)无论你想要什么,我都建议使用CapitalCase


我认为没有任何一个绝对的指导方针。


只要你选择的任何内容在整个应用程序或数据库中都是一致的,我就不认为它真的很重要。

其它参考11


在我看来:



  1. 表名应为复数。

  2. 列名应该是单数。

  3. 没有

  4. 表名和列名的CamelCase(我的首选)或underscore_separated。



但是,正如已经提到的那样,任何惯例都比没有惯例更好。无论您如何选择,请将其记录下来,以便将来的修改遵循相同的约定。

其它参考12



  1. 绝对保持表名单数,人不是人


    1. 同样在这里

    2. 否。我已经看到了一些可怕的前缀,甚至可以说明正在处理的是一个表(tbl_)还是一个用户存储过程(usp_)。接下来是数据库名称......不要这样做!

    3. 是。我倾向于PascalCase所有的表名



其它参考13


我认为这些问题的最佳答案将由您和您的团队提供。拥有命名约定然后命名约定究竟是多么重要。


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


当然,寻找一些有关标准的信息是很好的,这就是你所要求的,但不要担心或担心你可能得到的不同答案的数量:选择一个对你来说更好的答案。


以防万一,这是我的答案:



  1. 是。表格是一组记录,教师或演员,所以......复数。


  2. 我不使用它们。

  3. 我经常使用的数据库 - Firebird - 将所有内容保持为大写,因此无关紧要。无论如何,当我编程时,我会以更易于阅读的方式编写名称,例如 releaseYear


其它参考14


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


一个好的命名约定需要时间来发展,但一旦它到位,它允许团队使用共同语言向前推进。一个好的命名约定随项目有机地增长。良好的命名约定可以轻松应对软件生命周期中最长和最重要阶段的变化 - 生产中的服务管理。


这是我的答案:



  1. 是的,表名称在引用一组交易,证券或交易对手时应该是复数。


  2. 是。 SQL表的前缀为tb_,视图的前缀为vw_,存储过程的前缀为usp_,触发器的前缀为tg_,后跟数据库名称。

  3. 列名称应为小写字母,以下划线分隔。



命名很难,但在每个组织中都有人可以命名,在每个软件团队中都应该有人负责仲裁标准,并确保命名问题,如 sec_id , sec_value 和 security_id 得到早期解决他们被纳入项目。


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



  • 使用客户的语言和
    您的解决方案域

  • 具有描述性

  • 保持一致

  • 消除歧义,反思和重构

  • 除非他们使用缩写
    很清楚每个人

  • 不要使用SQL保留关键字
    专栏名称


其它参考15


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


http://justinsomnia.org/writings/naming_conventions.html[20]

其它参考16


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

其它参考17


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


列名称:它应该是单数的,然后它传达它将保持原子值并将确认归一化理论。但是,如果有n个相同类型的属性,那么它们应该以1,2,...,n等为后缀。


前缀表/列:这是一个很大的主题,稍后会讨论。


套管:它应该是Camel的情况


我的朋友 Patrick Karcher ,我请求你不要写任何可能冒犯某人的内容,正如你写的那样,•此外,外键必须在不同的表格中一致地命名。它应该是合法的殴打不这样做的人。我的朋友帕特里克从未犯过这个错误,但我写的一般。如果他们一起打算为此打败你怎么办? :)

其它参考18


聚会很晚,但我还想加上关于列前缀的两分钱


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


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


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


我认为这两个论点都存在缺陷。不使用前缀的两个问题的解决方案很容易。这是我的建议:


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


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


但我能听到你尖叫,它是如何解决1)?这完全是为了避免这种情况。是的,确实如此,但解决方案存在严重缺陷。为什么?好吧,前缀解决方案归结为:

为避免在出现歧义时必须指定table.column,请将所有列命名为table_column!

但这意味着从现在开始,您每次指定列时都必须编写列名。但是如果你不得不这样做,那么总是明确地写table.column有什么好处?确切地说,没有任何好处,它是要输入的完全相同的字符数。


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

其它参考19


基本数据库命名约定(和样式)(单击此处获取更多详细说明)[21]


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

其它参考20


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

其它参考21


表名称单数。让我们说你在模拟某人和他们的地址之间的关系。
例如,如果您正在阅读数据模型,那么您更喜欢
每个人可能住在0.1或许多地址。要么
每个人都可能住在0,1或许多地址。
我认为它更容易复数地址,而不是必须将人们重新定义为人。另外,集体名词常常与单数形式不同。

其它参考22



--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. 用于表和列名称的Pascal Case,用于索引和约束的前缀+ ALL上限。