关系表变数命名原则

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

所以如果我有一个 user表并且我有只有用户才有的产品, 表应该命名为 user_product还是仅仅命名为 product? 这是一对多关系。

如果我有几个产品说明为每个产品,它是 user_product_descriptionproduct_description或只是 description?使用正确的外键设置。命名它只有 description将是有问题的,因为我也可以有用户描述或帐户描述或任何东西。

如果我想要一个只有两列的纯关系表(多对多) ,该怎么办?user_stuff或者类似 rel_user_stuff的东西?如果是第一个,它和 user_product有什么区别?

109808 次浏览

单数和复数没有“正确”之分——这主要是品味的问题。

这在一定程度上取决于你的注意力。如果您将表看作一个单元,那么它包含“复数”(因为它包含许多行,所以使用复数名称比较合适)。如果您认为表名是用来标识表中的一行,那么您更喜欢使用“单数”。这意味着您的 SQL 将被视为处理表中的一行。这没关系,尽管这通常是一个过于简单化; SQL 工作在集合上(或多或少)。然而,我们可以用单数来回答这个问题。

  1. 因为您可能需要一个表“ user”、另一个表“ product”和第三个表来连接用户和产品,所以您需要一个表“ user _ product”。

  2. 因为描述适用于一个产品,所以你应该使用“ product _ description”。除非每个用户为自己命名每个产品..。

  3. “ user _ product”表是(或者可能是)一个带有产品 ID 和用户 ID 的表的示例,其他没有什么特别的。您可以使用相同的通用方式来命名两个属性表: ‘ user _ stuff’。像“ rel _”这样的装饰性前缀其实没什么帮助。例如,您将看到有些人在每个表名前使用‘ t _’。这可帮不上什么忙。

只要使用一致,复数也不错——但我更喜欢单数。

我会省略下划线,除非你想概述一个多对多的关系; 并使用一个初始大写,因为它有助于区分 ORM 中的东西。

但是有很多命名约定,所以如果你想使用下划线,只要它一直这样做就可以了。

所以:

User


UserProduct (it is a users products after all)

如果只有一个用户可以有任何产品然后

UserProductDescription

但如果产品是由用户共享的:

ProductDescription

如果将下划线保存为多对多关系,则可以执行以下操作:

UserProduct_Stuff

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

使用单数形式比使用复数形式更正确,你从哪里听说的?我更愿意说,复数形式更常见的命名数据库表... 在我看来,也更多的逻辑。表中通常包含不止一行)在概念模型中,尽管实体的名称通常是单数。

关于你的问题,如果“ Product”和“ ProductDescription”是在你的模型中具有标识(即实体)的概念,我会简单地称这些表为“ Products”和“ ProductDescription”。对于那些用于实现多对多关系的表,我最常用的变数命名原则是“ Sidea2SideB”,例如“ Student2Course”。

单数与复数: 选择一个并坚持下去。

列不应该是前缀/后缀/中缀,或者无论如何都不应该用对它是一个列的引用来固定。桌子也一样。不要将表命名为 EMPLOYEE _ T 或 TBL _ EMPLOYEES,因为一旦将其替换为视图,事情就会变得非常混乱。

不要在名称中嵌入类型信息,比如 varchar 的“ vc _ firstname”,或者“ wind _ enum”。也不要在列名中嵌入约束,例如“ department _ fk”或“ employee _ pk”。

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

不要把所有的钥匙都命名为“ ID”。引用相同事物的键,在所有表中应该有相同的名称。用户 id 列可以在用户表和引用该用户的所有表中称为 USER _ ID。只有当不同的用户扮演不同的角色时,才会重命名它,例如 Message (sender _ user _ id,副手 _ user _ id)。这在处理较大的查询时非常有帮助。

关于案件:

thisiswhatithinkofalllowercapscolumnnames.


ALLUPPERCAPSISNOTBETTERBECAUSEITFEELSLIKESOMEONEISSCREAMINGATME.


CamelCaseIsMarginallyBetterButItStillTakesTimeToParse.


i_recommend_sticking_with_lower_case_and_underscore

一般来说,命名“映射表”以匹配它所描述的关系比命名被引用的表更好。用户可以与产品有任意数量的关系: user_likes_productuser_bought_productuser_wants_to_buy_product

表•姓名

最近学的单数是正确的

是的。复数 在表名中是一个没有阅读任何标准材料和没有数据库理论知识的人的确切标志。

标准的一些美妙之处在于:

  • 它们都是相互融合的
  • 他们一起工作
  • 它们是由比我们更伟大的思想写成的,所以我们不必这样做 和他们辩论。

标准表名指的是表中的每个 划船,它用于所有的废话,而不是表的总内容(我们知道 Customer表包含所有的 Customer)。

关系,动词短语

在已经建模的真正的关系数据库中(相对于1970年以前的记录文件系统(以 Record IDs为特征,为了方便而在 SQL 数据库容器中实现) :

  • 这些表是数据库的 实验对象,因此它们是 名词,同样是单数
  • 表之间的关系是发生在名词之间的 行动,因此它们是 动词(即它们不是任意编号或命名的)
  • 就是 说重点
  • 所有可以从数据模型直接读取的内容(请参考我最后的示例)
  • (独立表(层次结构中最顶层的父表)的谓词是它是独立的)
  • 因此,动词短语是经过精心挑选的,因此它是最有意义的,并且避免使用通用术语(经验使这变得更容易)。动词短语在建模过程中很重要,因为它有助于解析模型,即。澄清关系、识别错误和更正表名。
[ * * 图表 _ A * * ][图表 _ A ]

当然,这种关系在 SQL 中是作为子表中的 CONSTRAINT FOREIGN KEY实现的(稍后会详细介绍)。这是 动词短语(在模型中) ,它代表的 说重点(从模型中读取) ,以及 FK 约束名称:

    Initiates
Each Customer Initiates 0-to-n SalesOrders
Customer_Initiates_SalesOrder_fk

表•语文

然而,在描述的表格,特别是在技术语言,如谓词,或其他文档,使用单数和复数,因为他们自然在英语语言。请记住,表是以单行(关系)命名的,语言引用每个派生行(派生关系) :

    Each Customer initiates zero-to-many SalesOrders

没有

    Customers have zero-to-many SalesOrders

因此,如果我得到了一个表“ user”,然后我得到了只有用户才会拥有的产品,那么这个表应该命名为“ user-product”还是仅仅“ product”?这是一对多的关系。

(这不是一个命名约定问题; 这是一个 db 设计问题。)user::product是否为1: : n 并不重要。重要的是 product是否是一个独立的实体,它是否是一个 独立表,即。它可以独立存在。所以是 product而不是 user_product

如果 product只存在于 user的上下文中,即它是 附属表,因此是 user_product

[ * * 图表 _ B * * ][图表 _ B ]

再进一步,如果我(出于某种原因)对每个产品都有几个产品描述,它是“用户-产品-描述”还是“产品-描述”,还是仅仅是“描述”?当然要有正确的外键设置。.命名它只有描述将是有问题的,因为我也可以有用户描述或帐户描述或什么。

没错。基于上述,无论是 user_product_description还是 product_description都是正确的。这并不是为了将它与其他 xxxx_descriptions区分开来,而是为了让名称知道它属于哪里,前缀是父表。

如果我想要一个只有两列的纯关系表(多对多) ,那么这个表会是什么样子呢?“用户物品”或者类似于“ rel-user-stuff”的东西?如果是第一个,它与“用户产品”有什么区别呢?

  1. 希望关系数据库中的所有表都是纯关系的、规范化的表。不需要在名称中标识它(否则所有表都将是 rel_something)。

  2. 如果它包含 只有双亲的 PK (它将逻辑层次上不存在的 合乎逻辑 n: : n 关系解析为 身体上的表) ,那么它就是 相联表。是的,通常该名称是两个父表名称的组合。

    • 请注意,在这种情况下,动词短语应用于,并被理解为,从父母到父母,忽略子表,因为它在生活中的唯一目的是关联两个父母。

      [ * * Diagram _ C * * ][ Diagram _ C ]
    • 如果它是 没有一个关联表(即。除了两个 PK 之外,它还包含数据) ,然后适当地命名它,并且动词短语应用于它,而不是关系结束时的父节点。

      [ * * 图表 _ D * * ][图表 _ D ]
  3. 如果您最终得到两个 user_product表,那么这是一个非常响亮的信号,表明您没有规范化数据。因此,回顾几个步骤,并这样做,并准确和一致地命名表。然后这些名字会自己解决。

变数命名原则

如果你们推荐某种变数命名原则标准,欢迎链接。

您正在做的事情非常重要,它将影响到每个级别的易用性和理解性。因此,一开始就尽可能多地了解情况是有好处的。在您开始使用 SQL 编码之前,这些内容的大部分相关性都不清楚。

  1. Case 是要解决的第一个问题。全部大写是不可接受的。混合大小写是正常的,特别是当用户可以直接访问这些表时。请参考我的数据模型。请注意,当搜索引擎使用某种只有小写的 NonSQL 时,我给出了这一点,在这种情况下,我包含了下划线(根据您的示例)。

  2. 维护一个 数据聚焦,而不是应用程序或使用焦点。我们从1984年就有了 开放式体系结构,数据库应该独立于使用它们的应用程序。

这样,随着它们的增长,并且不止一个应用程序使用它们,命名将保持有意义,并且不需要更正。(完全嵌入单个应用程序的数据库不是数据库。)仅将数据元素命名为数据。

  1. 要非常周到,并且表和列的命名非常 准确地说。如果它是 DATETIME数据类型,不要使用 UpdatedDate,使用 UpdatedDtm。如果含有剂量,不要使用 _description

  2. 跨数据库使用 始终如一非常重要。不要在一个地方使用 NumProduct表示产品数量,在另一个地方使用 ItemNoItemNum表示产品数量。对于 number-of 使用 NumSomething,对于标识符使用 SomethingNoSomethingId

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

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

    • 第一个例外是对于 PK,它们需要特殊的处理,因为您始终使用连接编码它们,并且希望键从数据列中脱颖而出。永远使用 user_id,不要使用 id

      • 请注意,这是 没有,一个用作前缀的表名,但是对于键的组件来说是一个合适的描述性名称: user_id是标识用户的列,而不是 user表的 id
        • (当然,在记录归档系统中除外,在这种系统中,文件是由代理访问的,没有关系密钥,它们只有一个,而且是同一个东西)。
      • 总是使用完全相同的名称为键列无论 PK 是携带(迁移)作为一个 FK。
      • 因此,user_product表将有一个 user_id作为其 PK (user_id, product_no)的组件。
      • 当你开始编写代码的时候,这个相关性就会变得清晰起来。首先,在许多表上使用 id,很容易在 SQL 编码中混淆。其次,其他任何人,最初的编码器不知道他想做什么。如果按上面的方式处理键列,那么这两种情况都很容易防止。
    • 第二个例外是有多个 FK 引用相同的父表,在子表中进行。根据 关系模型,使用 角色名称来区分意义或用法,例如。AssemblyCodeComponentCode代表两个 PartCodes。在这种情况下,没有是否使用未分化的 PartCode作为其中之一。要精确。

      图 E

  5. 前缀
    如果有超过100个表,则在表名前加上“主题区域”:

    参考表的 REF_
    OE_ 用于订单输入集群等。

    只是在物理层面,而不是逻辑层面(它使模型杂乱无章)。

  6. 后缀
    永远不要在表上使用后缀,在其他任何事情上都要使用后缀。这意味着在数据库的逻辑和正常使用中,没有下划线; 但在管理方面,下划线用作分隔符:

    _V 视图(当然,前面是 TableName主视图)
    _fk 外键(约束名,而不是列名)
    _cac缓存
    _seg
    _tr 事务(存储过程或函数)
    _fn 函数(非事务性)等。

格式为表或 FK 名称、下划线、操作名称、下划线和后缀。

这一点非常重要,因为当服务器给出错误消息时:

_ _ _ _ blah blah blah error on object_name

你很清楚哪个物体被侵犯了,它想做什么:

_ _ _ _ blah blah blah error on Customer_Add_tr

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

    Customer_Initiates_SalesOrder_fk
    Part_Comprises_Component_fk
    Part_IsConsumedIn_Assembly_fk

使用 Parent_Child_fk序列,而不使用 Child_Parent_fk是因为(a)当您查找它们时,它以正确的排序顺序出现; (b)我们总是知道所涉及的子元素,我们猜测的是哪个父元素。然后,错误消息令人愉快:

_ _ _ _ Foreign key violation on Vendor_Offers_PartVendor_fk.

这对于那些为数据建模的人来说非常有效,因为动词短语已经被识别出来了。对于其余的,记录归档系统等,使用 Parent_Child_fk

  1. 索引是特殊的,所以它们有自己的变数命名原则,由 abc 0组成,每个字符位置从1到3:

唯一的,或非唯一的 _
C群集,或非群集的 _
_分离器

其余的:
- 如果键是一列或极少数列:
_ _ _ _ ColumnNames

- If the key is more than a few columns:

PK主键(每个型号)
AK[*n*]备用密钥(IDEF1X 术语)

注意,表名称是索引名称中必需的 没有,因为它总是显示为 table_name.index_name.

因此,当 Customer.UC_CustomerIdProduct.U__AK出现在错误消息中时,它会告诉您一些有意义的信息。查看表上的索引时,可以很容易地对它们进行区分。

  1. 找到一个有资格和专业的人,并跟随他们。看看他们的设计,仔细研究他们使用的命名规范。问他们任何你不明白的具体问题。相反,如果有人对命名惯例或标准表现出不屑一顾,那就赶紧跑吧。这里有一些可以帮助你开始:
  • 他们包含上述所有的实际例子。问问题重新命名问题在这个线程。
  • 当然,这些模型实现了几个 其他标准,超出了命名约定; 您可以暂时忽略这些标准,也可以随意询问特定的 新问题
  • 它们每个都有几页,因此您必须单击这些链接。
  • 请注意,PDF 文件有完整的导航,所以点击蓝色玻璃按钮,或对象的扩展标识:
  • 不熟悉关系建模标准的读者可能会发现 IDEF1X 符号 很有帮助。

订单输入及库存 符合标准的地址

基于 PHP/MySQL 的简单办公室间 公报 系统

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

问题解答

在注释空间中无法合理地回答这个问题。

拉里 · 勒斯蒂格:
即使是最微不足道的例子。
如果一个客户拥有零对多产品,一个产品拥有一对多组件,一个组件拥有一对多供应商,一个供应商销售零对多组件,一个销售代表拥有一对多客户,那么持有客户、产品、组件和供应商的表格的“自然”名称是什么?

你的评论中有两个主要问题:

  1. 你声明你的例子是“最微不足道的”,然而,它绝非如此。鉴于这种矛盾,我不确定你是否是认真的,是否有技术能力。

  2. 这种“微不足道”的推测有几个严重的标准化(DB 设计)错误。

  • 除非你纠正这些错误,否则它们是不正常的,不正常的,而且它们没有任何意义。您也可以将它们命名为读数不正常 _ 1、读数不正常 _ 2等等。

  • 你有“供应商”谁不提供任何东西; 循环参考(非法的,不必要的) ; 客户购买产品没有任何商业文书(如发票或销售订单)作为购买的基础(或客户“拥有”产品未解决的多对多关系; 等等。

  • 一旦标准化,并且确定了所需的表,它们的名称就会变得很明显。

无论如何,我会尽力为您提供服务。也就是说,我得给它增加点意义,不知道你是什么意思,所以请忍耐一下。这些严重的错误太多以至于无法列出,而且考虑到备用规格,我不确定我已经把它们全部改正了。

  • 我将假设,如果产品是由组件组成的,那么该产品是一个组装,并且这些组件在多个组装中使用。

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

投机与标准化模型

如果您不知道,正方形角(独立)和圆角(相关)之间的差异是显着的,请参考 IDEF1X 符号链接。同样,实线(识别)与虚线(非识别)。

... 什么是“自然”的名称表持有客户,产品,零部件和供应商?

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

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

说重点

投票咖啡:
在 Ronnis 的例子中,两个表(user _ like _ product,user _ buy _ product)之间存在多种关系,您如何处理这个场景?我可能会误解,但这似乎会导致使用您详细说明的约定产生重复的表名。

假设没有标准化错误,那么 User likes Product是一个谓词,而不是一个表。别把他们搞糊涂了。请参考我的答案,其中涉及到主语、动词和谓语,以及我对上述拉里的回应。

  • 每个表包含一个 准备好了的事实(每行是一个事实)。谓词(或命题)不是事实,它们可能是真的,也可能不是真的。

  • 关系模型基于一阶谓词演算(通常称为一阶逻辑)。谓语是一个简单、精确的英语单句,它的评价是真或假。

  • 此外,每个表表示或实现了 很多谓词,而不是一个。

  • 查询是对一个谓词(或许多个连接在一起的谓词)的测试,其结果是 true (事实存在)或 false (事实不存在)。

  • 因此,应该像我的答案(命名约定)中详细说明的那样,为行、事实和谓词命名表(无论如何,它是数据库文档的一部分) ,但是作为一个单独的谓词列表。

  • 这并不是说它们不重要。它们非常重要,但我不会把它们写在这里。

  • 那就快点。因为 关系模型是建立在 FOPC 之上的,所以整个数据库可以说是一组 FOPC 声明,一组谓词。但是(a)谓词的类型有很多种,(b)一个表并不代表一个谓词(它是 很多谓词的物理实现,以及不同的 类别谓词的物理实现)。

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

  • “理论家”只知道一些谓词,他们不明白,因为 RM是建立在 FOL 上的,所以整个数据库是一组谓词,而且是不同类型的。

  • 当然,他们从少数几个他们知道的人中选择荒谬的: EXISTING_PERSON; PERSON_IS_CALLED。如果不是这么悲伤,那就太搞笑了。

  • 还要注意的是,Standard 或原子表名(命名行)对于所有的废话(包括附加到表的所有谓词)都非常有用。相反,“表表示谓词”的名称不能,这对于“理论家”来说是好的,他们对谓词了解甚少,但对其他方面却不理解。

  • 与数据模型相关的谓词,被表示为 进去模型,它们有两个顺序。

  1. 一元谓语
    第一个集合是 图解式的,而不是文本: 符号本身。它们包括各种存在的、面向约束的和描述符(属性)谓词。
  • 当然,这意味着只有那些能够“读取”标准数据模型的人才能够读取这些谓词。这就是为什么那些“理论家”,被他们的纯文本思维严重削弱,不能阅读数据模型,为什么他们坚持他们1984年以前的纯文本思维。
  1. 二进制谓词
    第二个集合是那些在事实之间形成 人际关系的集合。这是关系线。动词短语(详见上文)标识已实现的谓词(提议)(可以通过查询对其进行测试)。没有比这更明确的了。
  • 因此,对于熟悉标准数据模型的人来说,模型中记录了所有谓词 相关的。它们不需要单独的谓词列表(但是不能从数据模型“读取”所有内容的用户需要!).

  • 这是一个 资料模型 ,其中我已经列出了谓词。我之所以选择这个例子,是因为它显示了存在主义等谓词,以及关系谓词,唯一没有列出的谓词是描述符。在这里,由于探索者的学习水平,我把他当作一个使用者。

因此,在两个父表之间发生多个子表的事件不是问题,只需将它们命名为存在事实,并规范化它们的名称。

我为关联表的关系名称给出的动词短语规则在这里起作用。这里是一个 < strong > 谓词 vs 表 讨论,涵盖所有提到的要点,在总结。

有关谓词的正确使用以及如何使用它们(这里的上下文与响应注释的上下文完全不同) ,请访问 这个答案,然后向下滚动到 说重点部分。


查尔斯 · 伯恩斯:
我所说的顺序是指 Oracle 风格的对象,纯粹用于根据某种规则(例如“ add 1”)存储一个数字和它的下一个数字。由于 Oracle 缺少 auto-ID 表,我的典型用法是为表 PK 生成惟一的 ID。插入 foo (id,some data)值(foo _ s。Nextval,“ data”...)

这就是我们所说的 Key 或 NextKey 表。这么说吧。如果有 SubjectArea,请使用 COM _ NextKey 指示它在整个数据库中是常见的。

顺便说一下,这是一个非常糟糕的生成键的方法。根本不具备可伸缩性,但考虑到 Oracle 的性能,它可能“还不错”。此外,它还表明数据库中充满了代理,而不是这些领域中的关系代理。这意味着极差的表现和缺乏诚信。