关系表命名约定

我正在开始一个新项目,希望从一开始就让我的表和列名称。 例如,我总是在表名中使用复数,但最近学到的单数是正确的。

所以,如果我有一个“用户”表,然后我得到的产品,只有用户将有,如果表名为“user_product”或只是“产品”? 这是一对多的关系。

更进一步说,如果我有(出于某种原因)每个产品的几个产品描述,它会是“user_product_description”或“product_description”或只是“描述”? 当然,正确的外键设置..命名它只描述会有问题,因为我也可以有用户的描述或帐户描述或任何..

那么如果我想要一个只有两列的纯关系表(多对多),那么这将是什么样子呢? “user_stuff”或者像“rel_user_stuff”? 如果是第一个,那么会区分这个,例如“user_product”?

任何帮助,高度赞赏,如果有某种forms的命名约定标准那里你们推荐,随意链接。

谢谢

表•名称

最近才知道奇异是正确的

是。 谨防异教徒。 表格中的数字是没有阅读过任何标准材料,也没有数据库理论知识的人的明确标志。

关于标准的一些奇妙的事情是:它们全部相互结合; 他们一起工作; 而且它们是用比我们的思想更伟大的书写的,所以我们不必辩论它们。 标准表名是指表中的每一 ,用在所有的语言中,而不是表中的全部内容(我们知道Customer表包含所有客户)。

关系,动词短语

在已build模的真正的关系数据库中(而不是在SQL数据库容器中实现的logging归档系统):

  • 表是数据库的主题 ,因此它们是名词 ,也是单数
  • 表格之间的关系是在名词之间发生的动作 ,因此它们是动词 (即它们不被任意编号或命名)
  • 谓语
  • 所有这些都可以直接从数据模型中读取(最后参考我的示例)
  • (独立表(层次结构中最顶层的父表)的谓词是独立的)
  • 因此, 动词短语是仔细select,所以这是最有意义的,避免通用的条件(随着经验,这变得更容易)。 动词短语在build模过程中很重要,因为它有助于解决模型,即。 澄清关系,识别错误,纠正表名。

Diagram_A

当然,这个关系在SQL中作为一个外键约束在子表中实现(更多,稍后)。 这里是动词短语 (在模型中),它表示的谓词 (从模型中读取)和FK 约束名称

  Initiates Each Customer Initiates 0-to-n SalesOrders Customer_Initiates_SalesOrder_fk 

表格•语言

但是, 在描述表格时,特别是在Predicates等技术语言或其他文献中,使用单数和复数forms,这在英语中是很自然的。 记住表格是为单行(关系)命名的,而语言是指每个派生行(派生关系):

  Each Customer initiates zero-to-many SalesOrders 

  Customers have zero-to-many SalesOrders 

那么,如果我得到了一个“用户”表,然后我得到了只有用户才有的产品,那么该表应该被命名为“用户产品”还是“产品”呢? 这是一对多的关系。

(这不是一个命名约定的问题,这是一个数据库devise问题。)没有关系,如果user::product是1 :: n。 重要的是product是否是一个独立的实体,是否是一个独立的表格 , 它可以独立存在。 因此product ,而不是user_product

如果product仅存在于user的上下文中, 它是一个从属表 ,因此user_product

Diagram_B

更进一步说,如果我有(出于某种原因)每个产品的几个产品描述,它会是“用户产品描述”或“产品描述”或只是“描述”? 当然,正确的外键设置..命名它只描述会有问题,因为我也可以有用户的描述或帐户描述或其他。

那就对了。 根据以上所述, user_product_description xor product_description将是正确的。 这不是要区分它与其他的xxxx_descriptions ,而是要给名称一个属于它的位置的意义,前缀是父表。

那么如果我想要一个只有两列的纯关系表(多对多),那么这将是什么样子呢? “用户东西”或者像“rel-user-stuff”这样的东西? 如果是第一个,那么可以将其与“用户产品”区分开来吗?

  1. 希望关系数据库中的所有表都是纯关系,规范化表。 没有必要确定名称(否则所有的表都将是rel_something )。

  2. 如果它只包含两个父母的PK(它解决逻辑层次上不存在的作为一个实体的逻辑 n :: n关系到物理表中),那么这是一个关联表 。 是的,通常名称是两个父表名称的组合。

    • 请注意,这种情况下,动词短语适用于父母之间,而不是从父母到父母,因为它唯一的目的就是将父母联系起来。

      Diagram_C

    • 如果它不是一个关联表(即除了两个PK之外,它包含数据),则适当命名它,动词短语适用于它,而不是关系结束时的父母。

      Diagram_D

  3. 如果你最终得到两个user_product表,那么这是一个非常大的信号,你没有规范化数据。 所以回到几个步骤,并做到这一点,并准确,一致地命名表。 名字将自行解决。

命名约定

任何帮助,高度赞赏,如果有某种forms的命名约定标准那里你们推荐,随意链接。

你所做的事情非常重要,会影响到各个层面的使用和理解。 因此,从一开始就尽可能多地理解。 大部分的相关性不会很清楚,直到你开始在SQL中进行编码。

  1. 案例是第一个要解决的问题。 所有上限是不可接受的。 混合大小写是正常的,特别是如果用户可以直接访问这些表。 参考我的数据模型。 请注意,当search者使用一些疯狂的NonSQL,只有小写,我给,在这种情况下,我包括下划线(按照您的例子)。

  2. 保持数据重点 ,而不是应用程序或使用重点。 毕竟,自从1984年以来,我们已经拥有了开放式架构 ,数据库应该独立于使用它们的应用程序。

    这样,随着他们的成长,不只一个应用程序使用它们,命名仍然是有意义的,不需要更正。 (完全embedded到单个应用程序中的数据库不是数据库。)仅将数据元素命名为数据。

  3. 要非常体贴,并且非常准确地命名表格和列。 如果它是DATETIME数据types,请不要使用UpdatedDate ,请使用UpdatedDtm 。 如果含有剂量,请勿使用_description

  4. 在整个数据库中保持一致非常重要。 不要在一个地方使用NumProduct来表示产品的数量和在另一个地方的NumProductItemNum来表示项目的数量。 NumSomething使用NumSomething作为数字,而SomethingNoSomethingId作为标识符。

  5. 不要在表名或短代码(如user_first_name加上列名。 SQL已经提供了表名作为限定符:

      table_name.column_name -- notice the dot 
  6. 例外:

    • 第一个例外是PK,他们需要特殊的处理,因为你一直在join代码,并且你希望键从数据列中脱颖而出。 总是使用user_id ,而不是id

      • 请注意,这不是用作前缀的表名,而是键组件的正确描述性名称: user_id是标识用户的列,而不是user表的id
        • (当然除了logging归档系统,文件被代理人访问,没有关系密钥的地方,它们是同一件事情)。
      • 无论将PK作为FK运送(迁移)的位置,始终使用完全相同的名称作为键列。
      • 因此, user_product表将具有一个user_id作为其PK (user_id, product_no)一个组件。
      • 当你开始编码时,这个相关性将变得清晰。 首先,在许多表上使用一个id ,在SQL编码中很容易混淆。 其次,其他任何人,最初的编码器不知道他在做什么。 如果按照上述方式处理关键列,那么这两者都很容易防止。
    • 第二个例外是引用同一父表的多个FK引用的子节点。 根据关系模型 ,使用angular色名称来区分意义或用法,例如。 两个PartCodes AssemblyCodeComponentCode 。 在这种情况下,不要使用无差别的PartCode 。 准确。

      Diagram_E

  7. 字首
    如果您有超过100个表格,则在表格名称的前面添加一个主题区域:

    参考表的REF_
    订单input群集的OE_

    只有在物理层面上,不是逻辑上的(它使模型变得混乱)。

  8. 后缀
    切勿在表格中使用后缀,并且在其他所有内容上始终使用后缀。 这意味着在数据库的逻辑,正常使用中,没有下划线; 但在行政方面,下划线被用作分隔符:

    _V查看(当然,前面的主要TableName
    _fk外键(约束名称,而不是列名)
    _caccaching
    _seg细分
    _tr事务(存储过程或函数)
    _fn函数(非事务性)等

    格式是表格或FK名称,下划线和动作名称,下划线,最后是后缀。

    这是非常重要的,因为当服务器给你一个错误信息:

    ____ blah blah blah error on object_name

    你确切地知道什么对象被侵犯,以及它想要做什么:

    ____ blah blah blah error on Customer_Add_tr

  9. 外键 (约束,而不是列)。 FK的最佳命名是使用动词短语(减去“每个”和基数)。

    Customer_Initiates_SalesOrder_fk
    Part_Comprises_Component_fk
    Part_IsConsumedIn_Assembly_fk

    使用Parent_Child_fk序列,而不是Child_Parent_fk是因为(a)当你正在寻找它们时它以正确的sorting顺序显示,(b)我们总是知道涉及的孩子,我们猜测的是哪个父母。 错误信息是令人愉快的:

    ____ Foreign key violation on Vendor_Offers_PartVendor_fk

    对于那些懒得模拟数据的人来说,那些动词短语已经被识别出来了。 其余的,logging归档系统等使用Parent_Child_fk

  10. 指数是特殊的,所以他们有一个自己的命名约定, 按顺序组成 ,从1到3的每个字符位置:

    U唯一或_非唯一
    C群集,或者_非群集
    _分隔符

    其余部分:

    • 如果密钥是一列或几列:
      ____列名

    • 如果关键是超过了几列:
      ____ PK主键(按型号)
      ____ AK[*n*]备用密钥(IDEF1X术语)

    请注意,索引名称中不需要表名,因为它始终显示为table_name.index_name.

    所以当Customer.UC_CustomerIdProduct.U__AK出现在错误信息中时,它会告诉你一些有意义的东西。 当您查看表格中的索引时,可以轻松区分它们。

  11. 找一个合格和专业的人,并遵循他们。 看看他们的devise,并研究他们使用的命名约定。 询问他们关于你不了解的任何问题。 反过来说,任何不关心命名约定或标准的人都应该这样做。 这里有几个让你开始:

    • 它们包含所有上述的实例。 在这个线程中提出问题重命名问题。
    • 当然,除了命名约定之外,这些模型还实现了其他几个标准。 你现在可以忽略这些,或者随时提出具体的新问题
    • 它们每页都有几页,SO中的内联图像支持是针对鸟类的,而且它们不会在不同浏览器上持续加载; 所以你将不得不点击链接。
    • 请注意,PDF文件具有完整的导航,所以点击蓝色的玻璃button或扩展标识的对象:
    • 不熟悉关系build模标准的读者可能会发现IDEF1X Notation有帮助。

订单input和库存符合标准的地址

简单的用于PHP / MyNonSQL的办公室间公告系统

传感器监测具有全面的时间能力

问题的答案

这在评论空间中无法合理回答。

Larry Lustig:
…即使是最微不足道的例子显示…
如果一个客户有零对多的产品,一个产品有一对多的组件,一个组件有一对多的供应商,而一个供应商销售零对多的组件,而一个SalesRep拥有一对多的客户什么是持有客户,产品,组件和供应商的“自然”名称?

您的评论有两个主要问题:

  1. 你声明你的例子是“最微不足道的”,但是,它不是什么。 有了这样的矛盾,我不确定你是否认真,如果技术上有能力的话。

  2. 这种“微不足道的”猜测有几个总体标准化(DB Design)错误。

    • 直到你纠正这些,他们是不自然的和exception的,他们没有任何意义。 你不妨将它们命名为abnormal_1,abnormal_2等。

    • 你有“供应商”谁不提供任何东西; 循环引用(非法,不必要); 顾客在没有任何商业工具(如发票或销售订单)的情况下购买产品作为购买(或顾客“自己的”产品?)的基础; 未解决的多对多关系; 等等

    • 一旦这是规范化,并确定所需的表格,他们的名字将变得明显。 自然。

无论如何,我会尽力为您的查询服务。 这意味着我将不得不增加一些意识,不知道你的意思,所以请忍受我。 严重的错误是太多的列出,并给予了备用的规格,我不相信我已经纠正所有。

  • 我将假设如果产品是由组件组成的,那么产品就是一个组件,而这些组件被用在多个组件中。

  • 此外,由于“供应商销售零对多组件”,他们销售产品或组件,他们只销售组件。

投机与规范化模型

如果您不知道,方angular(独立)和圆angular(从属)之间的差异很大,请参阅IDEF1X表示法链接。 同样的实线(识别)与虚线(非识别)。

…什么是持有客户,产品,组件和供应商的“自然”名称?

  • 顾客
  • 产品
  • 组件(或者,AssemblyComponent,对于那些意识到一个事实标识另一个的人)
  • 供应商

现在我已经解决了表格,我不明白你的问题。 也许你可以发表一个具体的问题。

VoteCoffee:
他如何处理Ronnis在他的例子中发表的两个表格(user_likes_product,user_bought_product)之间存在多重关系的情景? 我可能会误解,但是这似乎会导致使用您详述的约定重复表名。

假设没有规范化错误, User likes Product是谓词,而不是表格。 不要混淆他们。 请参阅我的答案,它涉及主题,动词和谓词,以及我对上面拉里的回应。

  • 每个表格都包含一组事实(每一行都是事实),而不是谓词。 谓词(或命题)不是事实,它们可能或可能不是真实的。

    • 关系模型基于一阶谓词演算(一般称为一阶逻辑)。 一个谓词是一个简单,精确的英语单句子句,评估为真或假。
  • 一个查询是对一个谓词(或一系列谓词链接在一起)的testing,结果为真(事实存在)或错误(事实不存在)。

  • 因此,应按照我的Answer(命名约定)中的详细说明,对表进行命名,对于行,事实和谓词应该进行logging(无论如何,它都是数据库文档的一部分),但作为一个单独的谓词列表。

  • 这并不意味着他们并不重要。 他们非常重要,但是我不会在这里写下来。

  • 那么快点。 由于关系模型build立在FOL之上,整个数据库可以说是一组声明,一组谓词。 但是(a)谓词的种类很多,(b)一个表格并不代表一个谓词(它是许多谓词的物理实现,以及不同types的谓词)。

  • 因此,将表格命名为“它”所代表的谓词是荒谬的概念。

  • “理论家”只知道一些谓词,他们不了解,因为RM是在FOL上build立起来的,整个数据库就是一套Predicates,而且是不同types的。

    • 当然,他们从他们所知道的less数人中select荒谬的:EXISTING_PERSON; PERSON_IS_CALLED。 如果不那么难过,那会很搞笑的。

    • 还要注意的是,标准或primefaces表名(命名行)对于所有的语言(包括附在表中的所有谓词)都performance出色。 相反,白痴的“表格代表谓语”的名字不能。 对于“理论家”来说这是很好的,他们对于谓词的理解很less,但是否则就会受到阻碍。

  • 与数据模型相关的谓词在模型中expression,它们有两种。

    • 第一套是图表,而不是文字,forms:符号。 这些包括各种存在; 约束为导向的; 和描述符(属性)谓词。

    • 当然,这意味着只有那些可以读取标准数据模型的人才能阅读这些谓词。 这就是为什么那些被纯文本思维严重摧残的“理论家”不能读取数据模型,为什么他们坚持1984年以前的文本思维模式。

    • 第二套是形成事实之间关系的谓词。 这是关系线。 动词短语(详述如上)标识已经实现的谓词(可以通过查询来testing)。 没有比这更明确的了。

    • 因此,对于能够stream利地使用标准数据模型的人员,所有相关的谓词都logging在模型中。 他们不需要一个单独的Predicates列表(但用户呢!)。

  • 这是一个数据模型 ,我列出了谓词。 我之所以select这个例子,是因为它显示了存在论等等,谓词以及关系,唯一没有列出的谓词是描述符。 在这里,由于求职者的学习水平,我把他当作一个用户。

因此,两个父表之间的多个子表的事件不是问题,只要将它们命名为Existential Fact来表示它们的内容,并对这些名称进行规范化。

我在关联表的关系名称中使用的动词短语的规则在这里起作用。 这里是一个Predicate vs Table的讨论,总结了所有提到的要点。

对于一个好的简短描述,重新使用Predicates,以及如何使用它们(这里的回应与此处的注释是完全不同的),请访问此答案 ,然后向下滚动到Predicate部分。


Charles Burns:
按照顺序,我的意思是纯粹用于存储数字的Oracle风格的对象,根据某些规则(例如“加1”)来存储数字。 由于Oracle缺less自动ID表,因此我的典型用法是为表PK生成唯一的ID。 INSERT INTO foo(id,somedata)VALUES(foo_s.nextval,“data”…)

好的,这就是我们所说的Key或NextKey表。 这样命名。 如果您有SubjectAreas,则使用COM_NextKey指示它在数据库中是通用的。

顺便说一句,这是一个非常糟糕的方法来生成密钥。 根本没有可扩展性,但是随着Oracle的performance,这可能“很好”。 此外,它表明你的数据库充满代理,而不是在这些领域的关系。 这意味着性能极差,缺乏完整性。

单数还是复数都没有“正确” – 这主要是品味的问题。

这部分取决于你的重点。 如果您将表格视为一个单位,它将保留“复数”(因为它包含许多行 – 所以复数名称是适当的)。 如果您将表格名称视为在表格中标识行,则您更喜欢“单数”。 这意味着你的SQL将被认为是在表中的一行上工作。 没关系,尽pipe这通常是过于简单化了。 SQL在集合上工作(或多或less)。 但是,我们可以单数去解答这个问题的答案。

  1. 既然你可能需要一个表'用户',另一个'产品',第三个用户连接产品,那么你需要一个表'user_product'。

  2. 由于说明适用于产品,因此您可以使用“product_description”。 除非每个用户自己命名每个产品…

  3. “user_product”表是(或可能是)带有产品ID和用户ID的表格的示例,而不是其他的。 你用同样的方式命名两个属性表:'user_stuff'。 像“rel_”这样的装饰性前缀并没有真正的帮助。 例如,您会看到一些人在每个表名前使用“t_”。 这不是很多的帮助。

奇异与复数:挑一个并坚持下去。

列不应该加前缀/后缀/固定或反正固定引用它是一个列。 桌子也一样。 不要命名表EMPLOYEE_T或TBL_EMPLOYEES,因为第二个被replace为视图,事情变得非常混乱。

不要在名称中embeddedtypes信息,例如varchar的“vc_firstname”或者“flavour_enum”。 也不要在列名中embedded约束,例如“department_fk”或“employee_pk”。

实际上,我能想到的关于修复的唯一好处就是可以使用保留字如where_ttbl_orderuser_vw 。 当然,在这些例子中,使用复数将解决这个问题:)

不要命名所有的钥匙“ID”。 指向同一事物的键在所有表中都应该具有相同的名称。 用户ID列可以在用户表中被称为USER_ID,并且所有表都引用用户。 唯一一次重命名是当不同的用户正在扮演不同的angular色,如消息(sender_user_id,receiver_user_id)。 这在处理较大的查询时确实有帮助。

关于CaSe:

 thisiswhatithinkofalllowercapscolumnnames. ALLUPPERCAPSISNOTBETTERBECAUSEITFEELSLIKESOMEONEISSCREAMINGATME. CamelCaseIsMarginallyBetterButItStillTakesTimeToParse. i_recommend_sticking_with_lower_case_and_underscore 

一般来说,最好将“映射表”命名为匹配它描述的关系,而不是引用表的名称。 用户可以与产品有任何数量的关系: user_likes_productuser_bought_productuser_wants_to_buy_product

只要一致地使用复数,复数是不错的,但单数是我的select。

除非你想勾画一个多对多的关系,否则我会省略下划线。 并使用初始资本,因为它有助于区分ORM中的事物。

但是有很多命名约定,所以如果你想使用下划线,那么只要一致地完成。

所以:

 User UserProduct (it is a users products after all) 

如果只有一个用户可以有任何产品的话

 UserProductDescription 

但是,如果产品被用户共享:

 ProductDescription 

如果你保存你的下划线的多对多的关系,你可以做一些事情:

 UserProduct_Stuff 

在UserProduct和Stuff之间形成一个M-to-M – 从这个问题不确定多对多所需的确切性质。

单数forms不是更复数的forms,你听说过吗? 我宁愿说复数forms对命名数据库表更为常见……在我看来,还有更多的逻辑。 该表最常包含多行;)在概念模型中,实体的名称通常是单数的。

关于你的问题,如果“产品”和“产品描述”是在你的模型中有一个身份(即实体)的概念,我会简单地调用表'产品'和'产品描述'。 对于用于实现多对多关系的表,我经常使用命名约定“SideA2SideB”,例如“Student2Course”。