关系表命名规范

26 浏览
0 Comments

关系表命名规范

已关闭。此问题是基于个人观点的,目前不接受回答。


 

想要改进此问题吗? 更新问题,使其可以通过事实和引用来回答,编辑此帖子

社区在1年前审查后决定不重新开放此问题:

原关闭原因未解决


改进此问题

我正在开始一个新项目,希望将我的表格和列名起得正确。例如,我一直在使用表格名的复数形式,但最近才知道单数是正确的。

因此,如果我有一个表格user,我有一些只有用户拥有的产品,那么表格应该命名为user_product还是product?这是一对多的关系。

如果每个产品需要多个产品描述,是该使用user_product_descriptionproduct_description还是只使用description?在外键设置正确的情况下。只使用description会有问题,因为我也可能有用户描述或账户描述或其他描述。

如果我需要一个纯关系表(多对多),只有两列,应该使用user_stuff还是类似rel_user_stuff的内容?如果选择第一个,那么它和user_product有什么不同?

admin 更改状态以发布 2023年5月21日
0
0 Comments

单数与复数: 选择一种并坚持使用。

列不应该被用标识它是一列的引用前缀/后缀/插入或者以任何方式固定。表也是一样。不要给表命名为EMPLOYEE_T或TBL_EMPLOYEES,因为一旦它被替换为视图,事情就会变得非常混乱。

不要在名称中嵌入类型信息,例如将varchar命名为"vc_firstname",或者将约束嵌入列名称,如"department_fk"或"employee_pk"。

实际上,关于 *fixes,我能想到的唯一好处是,您可以使用保留字,如where_ttbl_orderuser_vw。当然,在这些示例中使用复数形式将解决这个问题 🙂

不要将所有键命名为"ID"。引用相同的事物的键在所有表中应该具有相同的名称。用户ID列可以在用户表中和所有引用用户的表中称为USER_ID。唯一需要重命名的是当不同的用户扮演不同的角色时,例如Message(sender_user_id,receiver_user_id)。当处理较大的查询时,这真的很有帮助。

关于大小写:

thisiswhatithinkofalllowercapscolumnnames.
ALLUPPERCAPSISNOTBETTERBECAUSEITFEELSLIKESOMEONEISSCREAMINGATME.
CamelCaseIsMarginallyBetterButItStillTakesTimeToParse.    
i_recommend_sticking_with_lower_case_and_underscore

一般来说,更好的方法是将"映射表"命名为描述其关系的名称,而不是参考表的名称。用户可以对产品有任意数量的关系:user_likes_productuser_bought_productuser_wants_to_buy_product

0
0 Comments

表格•名称

最近学到单数是正确的

是的。表格名称中的复数是表明某人根本没有阅读任何标准资料且没有数据库理论知识的确凿迹象。

关于标准的一些精彩之处包括:

  • 它们全部集成在一起
  • 它们相互配合
  • 它们是由比我们聪明的人编写的,因此我们不必争辩它们。

标准表格名称指的是表格中的每一行,该行在所有用语中均被使用,而不是表格的总内容(我们知道“Customer”表格包含所有的顾客)。

关系、动词短语

在真正的关系数据库中(已经被建模的数据库,而不是七十年代以前的记录归档系统[以Record IDs为特征,这些 ID 在 SQL 数据库容器中以方便使用):

  • 表格是数据库的主题,因此它们是名词,再次强调,是单数
  • 表格之间的关系是名词之间发生的动作,因此它们是动词(即它们不是任意编号或以任意方式命名)
  • 这就是谓语
  • 所有这些内容都可以直接从数据模型中读取(参见我在最后的示例)
  • (独立表的谓语(在层次结构中位于最上面的父表)是它是独立的)
  • 因此,动词短语要谨慎选择,以使其最有意义,并避免使用通用术语(随着经验的积累,这变得更容易)。在建模过程中,动词短语很重要,因为它有助于解决模型,即阐明关系,识别错误并更正表格名称。


[**Diagram_A**][Diagram_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”?这是一对多的关系。

(这不是一个命名约定的问题;这是一个数据库设计问题。)无论user::product是1::n还是其他,重要的是要确定product是否是一个独立的实体,以及它是否是一个独立的表格,即它可以自行存在。因此,应该使用product,而不是user_product

如果产品仅存在于“用户”的上下文中,即它是一个"从属表",因此是"user_product"。

并且,如果出于某种原因,我对每个产品都有几个产品描述,那么“user-product-description”或“product-description”或仅仅是“description”会如何?当然,设置适当的外键。仅将其命名为描述是有问题的,因为我也可能有用户描述或帐户描述或其他任何描述。

没错。根据上述情况,只有"user_product_description"和"product_description"之一是正确的。它不是为了将其与其他"xxxx_descriptions"区分开,而是为了给名称以它所属的意义,前缀是父表。

如果我想要一个只有两个列的纯关系表(多对多),它会是什么样子?是"user-stuff"还是类似于"rel-user-stuff"之类的东西? 如果是前者,那么这将与"用户产品"有何不同?

希望关系数据库中的所有表都是纯关系,标准化的表。没有必要在名称中识别它(否则所有的表都将是"rel_something")。

如果它仅包含两个父项的PK(将不存在于逻辑级别的逻辑n::n关系解析成物理表格),那么它就是"关联表"。是的,通常名称是两个父表名称的组合。

请注意,在这种情况下,动词短语应用于,读取自,从父级到父级,忽略子表,因为它的存在仅用于关联两个父级。

如果不是关联表(即除了两个PK之外,它还包含数据),则适当地命名它,并且动词短语适用于它,而不是关系末端的父表。

如果您最终有两个"user_product"表,那么这是一个非常强烈的信号,表明您尚未标准化数据。因此,返回几个步骤并准确、一致地命名表格。然后表名将解决本身。

如果有一些我们推荐的命名约定标准,可以随时链接。

您所做的事情非常重要,它将影响每个级别的易用性和理解。因此,在开始编写SQL之前,了解尽可能多的内容是很好的。

  1. 首要问题是处理大小写。全大写不可接受。混合大小写是常规操作,尤其是当表格可以直接被用户访问时。请参考我的数据模型。请注意,当使用一些只支持小写字母的非SQL时,我会采用这种方法,并在其中使用下划线(如您的示例所示)。

  2. 保持数据聚焦,而非应用或使用聚焦。我们从 1984 年起一直拥有 开放式架构,数据库应该是独立于使用它们的应用的。

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

  1. 非常准确地命名表格和列。如果是 DATETIME 数据类型,请不要使用 UpdatedDate,而是使用 UpdatedDtm。请求不要在包含剂量的情况下使用 _description

  2. 在整个数据库中保持一致性。不要在某个地方使用 NumProduct 表示产品数量,并在另一个地方使用 ItemNoItemNum 表示项的数量。请始终使用 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 表将具有其 PK 的一个组成部分 (user_id,product_no)
      • 当您开始编码时,这个相关性将会变得清晰。首先,在许多表格上使用 id 很容易在 SQL 编码中混淆。其次,除了最初的编码人员外,其他人都不知道他想要做什么。如果按照上述方式处理关键列,则可以轻松避免这两种问题。
    • 第二个例外是在相同的子级中携带多个 FK 引用相同的父表。根据关系模型,使用角色名称区分含义或使用方式,例如 AssemblyCodeComponentCode 用于两个 PartCodes。在这种情况下,不要为其中一个使用未区分的 PartCode。要精确。

    • Diagram_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. 索引很特殊,因此它们有自己的命名约定,由1到3个字符位置依次组成:

U 唯一,或_为非唯一项
C 簇集,或_为非簇集
_ 分隔符

对于其余的:
- 如果关键字只有一列或很少几列:
____ColumnName

- 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的简单办公室公告系统

传感器监控 具有完整的时间能力

问题的答案

无法在评论区合理回答。

Larry Lustig:
...即使是最微不足道的例子也可以显示...
如果一个客户有零到多个产品,而一个产品有一到多个部件,而一个部件有一到多个供应商,而一个供应商销售零到多个部件,而一个销售代表有一个到多个客户,那么包含客户、产品、部件和供应商的表的自然名称是什么?

您的评论存在两个主要问题:

  1. 您宣布自己的例子是“最微不足道的”,但实际上它并不是。因此,我不确定您是否认真,是否具备技术能力。

  2. 一个“琐碎的”推测有几个明显的规范化(DB设计)错误。

  • 在你纠正这些错误之前,它们是不自然和异常的,它们没有任何意义。你还不如把它们命名为abnormal_1、abnormal_2等。

  • 你有一些“供应商”并没有供应任何东西; 循环引用(非法和不必要); 客户购买产品没有任何商业文书(如发票或销售订单)作为购买的基础(或者客户“拥有”产品吗?); 未解决的多对多关系; 等等。

  • 一旦规范化并且确定所需的表格,它们的名称将变得明显。当然。

无论如何,我会尽力回答您的问题。这意味着我将不知道你的意思而添加一些意义,所以请耐心等待。由于规范化错误太多而无法列出,并且鉴于规格的稀疏性,我不自信已经全部纠正。

  • 我假设如果产品由组件组成,则产品是装配件,组件在多个组装件中使用。

  • 而且,由于“供应商销售零到多个组件”,他们不销售产品或装配件,只销售组件。

推测与规范化模型

如果您不知道方形角(独立)和圆形角(依赖)之间的区别很大,请参见 IDEF1X 符号 链接。同样,实线(标识)和虚线(非标识)之间也有区别。

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

  • Customer
  • Product
  • Component(或者AssemblyComponent,对于那些意识到一个事实可以标识另一个事实的人)
  • Supplier

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

谓词

VoteCoffee:
你如何处理Ronnis在他的例子中提到的两个表之间存在多个关系的场景(user_likes_product、user_bought_product)?我可能误解了,但这似乎导致使用您详细介绍的约定的重复表名。

假设没有规范化错误,User likes Product是一个谓词,而不是一个表。不要混淆它们。请参考我的答案,涉及到主语、谓语和谓词,以及我对Larry的回应。

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

  • 关系模型是基于一阶谓词演算(更常称为一阶逻辑)的。谓词是一句简单、准确的英语句子,可以为真或假。

  • 此外,每个表都代表或实现了多个谓词,而不是仅有一个。

  • 查询是对一个或多个谓词进行测试(串联在一起),结果是真(事实存在)或假(事实不存在)。

  • 因此,表应该按照我所提供的命名规则进行命名(命名约定),行为事实,谓词应该记录下来(当然,它是数据库文档的一部分),但是应该作为一个单独的谓词清单。

  • 这并不是说它们不重要。它们非常重要,但我不会在这里详细介绍。

  • 那么,由于关系模型是基于一阶谓词演算的,整个数据库可以被视为一组一阶谓词声明,即一组谓词。但是,(1)有许多类型的谓词,(2)表不代表一个谓词(它是不同谓词的物理实现,并且是不同类型的谓词)。

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

  • “理论家”只了解一些谓词,他们不了解RM是基于FOL的事实,整个数据库是一组不同类型的谓词。

  • 当然,他们从他们所知道的少数谓词中选择荒谬的谓词:EXISTING_PERSONPERSON_IS_CALLED。如果不是这么悲哀,就会很滑稽。

  • 还要注意,标准或原子表名(为行命名)对于所有措辞(包括附加到表的所有谓词)都非常有效。反过来,“表代表谓词”名称不能,这对于“理论家”是可以的,他们对谓词了解很少,但对于其他人不是。

  • 与数据模型相关的谓词在模型中表达,它们分为两个级别。

    1. 一元谓词
      第一组是图表的,而不是文本:符号本身。这些包括各种存在性;约束导向;和描述符(属性)谓词。
    • 当然,这意味着只有那些可以“阅读”标准数据模型的人才能阅读这些谓词。这就是为什么“理论家”由于他们只能看到文本,而无法理解数据模型,所以他们仍然坚持他们实施在1984年之前的只读文本的思维方式的原因。
    1. 二元谓词
      第二组是形成事实之间的关系的谓词。这是关系线。 动词短语(详见上文)标识了已经实现的谓词、命题(可以通过查询进行测试)。没有比这更明确的了。
    • 因此,对于熟悉标准数据模型的人,所有相关的谓词都记录在模型中。他们不需要一个单独的谓词清单(但是那些不能从模型中“阅读”所有内容的用户需要!)。

    • 这里有一个数据模型,我列出了谓词。我选择了这个例子,因为它展示了存在性等谓词,以及关系谓词,唯一没有列出的是描述符。在这里,由于求职者的学习水平,我将他视为用户。

    因此,在两个父表之间存在多个子表的事件不是问题,只需要根据其内容将它们命名为存在事实,并规范化这些名称即可。

    我提供的有关关联表关系名称的动词短语规则在这里发挥作用。这里有一个谓词与表格的讨论,总结了所有提到的点。

    关于正确使用谓词以及如何使用它们的一个简短的好描述(这与在这里回复评论的上下文相当不同),请访问此答案,并滚动到谓词部分。


    Charles Burns:
    对于序列,我指的是用于存储数字及其下一个编号的Oracle风格对象,根据某些规则(如“加1”)。由于Oracle缺少自动ID表,我的典型用法是为表PK生成唯一ID。INSERT INTO foo(id,somedata)VALUES(foo_s.nextval,“data”…)

    好的,这就是我们所谓的关键或下一个关键表。将其命名为这样。如果您有主题,使用COM_NextKey表示它在整个数据库中通用。

    顺便说一句,这是一种非常糟糕的生成关键词的方法。根本没有可扩展性,但是有了Oracle的性能,它可能是“完美的”。此外,它表明您的数据库充满了代理,而在这些领域中不是关系型的。这意味着极差的性能和缺乏完整性。

    0