首页 文章

数据库,表和列命名约定? [关闭]

提问于
浏览
669

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

  • 表名应该是复数吗?

  • 列名是否应该是单数?

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

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

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

23 回答

  • 18

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

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

    • 表格的奇异名称

    • 列的奇异名称

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

    • Pascal套管(a.k.a . 上骆驼套)

  • 90

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

    • 我的偏好是复数

    • 是的

    • 表:通常没有前缀是最好的 . 专栏:没有 .

    • 表和列:PascalCase .

    阐述:

    (1) What you must do. 每次都必须以某种方式做很少的事情,但有一些事情 .

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

    • 此外, foreign keys must be named consistently 在不同的表中 . 殴打不这样做的人应该是合法的 . 我认为虽然定义的外键约束通常很重要,但一致的外键命名始终很重要

    • 您的数据库必须 internal conventions . 即使在后面的部分中,您会看到我非常灵活,但在数据库中命名必须非常一致 . 无论您的客户表是客户还是客户,都不如在同一个数据库中以相同的方式执行 . 你可以翻转硬币来确定如何使用下划线,但是你必须以同样的方式继续使用它们 . 如果你不这样做,你就是一个自卑的人 .

    (2) What you should probably do.

    • 表示不同表上相同类型数据的字段应命名为相同 . 一个表上没有Zip而另一个表上没有ZipCode .

    • 要分隔表名或列名中的单词,请使用PascalCasing . 使用camelCasing本质上不会有问题,但是's not the convention and it would look funny. I'会在一瞬间解决下划线问题 . (你可能不像过去那样使用ALLCAPS.OBNOXIOUSTABLE.ANNOYING_COLUMN在20年前在DB2中没问题,但现在不行 . )

    • 不要人为地缩短或缩写单词 . 名称长而清晰比短而混乱更好 . 超短名称是更黑暗,更野蛮时代的延续 . Cus_AddRef . 究竟是什么?保管收件人参考?客户额外退款?自定义地址推荐?

    (3) What you should consider.

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

    • 始终如一地使用下划线并用于特定目的 . 只有通用表名称应该与PascalCasing足够清楚;你不要在下一个子弹中找到地址 .

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

    • 很少(如果有的话)你想要列前缀 .

  • 5

    好吧,因为我们正在考虑意见:

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

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

    SELECT person.Name
    FROM People person
    

    有点像LINQ的“人在人选人 . 名” .

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

  • 25

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

    • 任何命名标准都优于无标准 .

    • 没有"one true"标准,我们都有自己的喜好

    • 如果已经有标准,请使用它 . 不要制定另一个标准或混淆现有标准 .

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

    对于字段,我们希望字段名称包含表格的前缀/ acryonm(即cust_address1),我们也更喜欢使用标准的后缀集合(对于PK为_id,对于“代码”为_cd,对于“name”为_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
    

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

  • 32
    • 不可以 . 表格应以它所代表的实体命名 . 人,而不是人是你如何指代其中一个记录所代表的人 .

    • 再次,同样的事情 . FirstName列确实不应该被称为FirstNames . 这一切都取决于您想要用列表示的内容 .

    • 没有 .

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

    好 . 这是我的0.02美元

  • 3

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

    Data element name on Wikipedia

    “表是实体的集合,并遵循集合命名准则 . 理想情况下,使用集合名称:例如,Personnel .Polyral也是正确的:Employees . 不正确的名称包括:Employee,tblEmployee和EmployeeTable . ”

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

  • 3

    我们的偏好:

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

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

    • 列名是否应该是单数?
      通常,是的,除非您违反规范化规则 .

    • 我应该为表格或列添加前缀吗?
      主要是平台偏好 . 我们更喜欢使用表名为列添加前缀 . 无论如何我们都不会更新 . )

    这也是避免关键字冲突的好方法(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表) .

    或者您在customer_type和customer_category之间存在M-M关系(某些类别只能使用某些类型)

    customer_category_customer_type_id

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

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

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

  • 8

    看一下ISO 11179-5:命名和识别原则你可以在这里找到它:http://metadata-standards.org/11179/#11179-5

    我在这里写了一段时间的博客:ISO-11179 Naming Conventions

  • 4

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

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

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

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

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

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

  • 262

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

    All columns should be named with a prefix that is unique to the table they are defined in.

    例如 . 给定表“customer”和“address”,我们分别使用“cust”和“addr”的前缀 . “customer”将包含“cust_id”,“cust_name”等 . “地址”将包含“addr_id”,“addr_cust_id”(FK返回给客户),“addr_street”等 .

    当我第一次被提出这个标准时,我已经死了;我讨厌这个主意 . 我无法忍受所有额外打字和冗余的想法 . 现在我已经有了足够的经验,我永远不会回去 .

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

    You can search your entire code base and reliably find every line of code that touches a particular column.

    #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%';
    
  • 234

    我对这些的看法是:

    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个 property

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

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

    我认为这些都没有一套绝对的指导方针 .

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

  • 44

    在我看来:

    • 表名应为复数 .

    • 列名应该是单数 .

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

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

  • 10
    • 绝对保持表名单数,人不是人

    • 同样在这里

    • 不,我've seen some terrible prefixes, going so far as to state what were dealing with is a table (tbl_) or a user store procedure (usp_). This followed by the database name... Don' t做到了!

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

  • 14

    我认为这些问题的最佳答案将由您和您的团队提供 . 有一个命名约定,那么命名约定究竟是多么重要 .

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

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

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

    • 是的 . 表是一组记录,教师或演员,所以......复数 .

    • 是的 .

    • 我不使用它们 .

    • 我经常使用的数据库 - Firebird - 将所有内容保持为大写,因此它不会编程我以更易于阅读的方式编写名称,例如releaseYear .

  • 13

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

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

    这是我的答案:

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

    • 是的 .

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

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

    命名很难,但在每个组织中都有人可以命名,在每个软件团队中都应该有人负责仲裁标准并确保命令问题如sec_id,sec_value和security_id在项目融入之前得到解决 .

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

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

    • 具有描述性

    • 保持一致

    • 消除歧义,反思和重构

    • 除非每个人都清楚,否则不要使用缩写

    • 不要将SQL保留关键字用作列名

  • 11

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

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

  • 8

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

  • 19

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

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

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

    套管:它应该是Camel的情况

    我的朋友, Patrick Karcher ,我请求你不要写任何可能冒犯某人的东西,就像你写的那样,"•Further, foreign keys must be named consistently in different tables. It should be legal to beat up someone who does not do this." . 我从来没有做过这个错误我的朋友帕特里克,但我写的一般 . 如果他们一起打算为此打败你怎么办? :)

  • 2

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

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

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

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

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

    Always use the table name in your SQL. E.g., always use table.column instead of column.

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

    但我能听到你尖叫,它是如何解决1)?这完全是为了避免这种情况 . 是的,确实如此,但解决方案存在严重缺陷 . 为什么?那么,前缀解决方案归结为:
    为避免在出现歧义时指定table.column,请将所有列命名为table_column!
    但这意味着从现在开始,您每次指定列时都必须编写列名 . 但是如果你必须这样做,那么's the benefit over always explicitly writing table.column? Exactly, there is no benefit, it'要输入的字符数完全相同 .

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

  • 14

    Essential Database Naming Conventions (and Style)(点击此处获取更多详细说明)

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

  • 4
    SELECT 
       UserID, FirstName, MiddleInitial, LastName
    FROM Users
    ORDER BY LastName
    
  • -1

    表名称单数 . 假设您正在模拟某人与其地址之间的关系 . 例如,如果您正在阅读数据模型,您更喜欢“每个人可能住在0,1或许多地址 . ”或者'每个人可能住在0,1或许多地址 . '我认为更容易复数地址,而不是将人们改写为人 . 另外,集体名词常常与单数形式不同 .

  • 66
    --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
    );
    

    这些是我所教授的惯例,但你应该适应你开发软管使用的任何东西 .

    • 复数 . 它是一组实体 .

    • 是的 . 该属性是实体的单一属性的表示 .

    • 是的,前缀表名允许轻松跟踪所有约束索引和表别名的命名 .

    • Pascal用于表和列名称的大小写,前缀为索引和约束的所有大写字母 .

相关问题