我正在开始一个新项目,并希望从一开始就获得我的表名和列名。例如,我一直在表名中使用复数,但最近学习的单数是正确的。
所以,如果我有一个表“用户”,然后我得到了只有用户才能拥有的产品,该表应该命名为“user_product”还是只是“产品”?这是一对多的关系。
再进一步,如果我(出于某种原因)每个产品都有几个产品描述,它是“user_product_description”还是“product_description”还是只是“description”?当然,使用正确的外键设置..仅命名它是有问题的,因为我也可以有用户描述或帐户描述或其他任何东西..
如果我想要一个只有两列的纯关系表(多对多),这会是什么样子?“user_stuff”或者类似“rel_user_stuff”的东西?如果是第一个,它与例如“user_product”有什么区别?
非常感谢任何帮助,如果你们推荐某种命名约定标准,请随时链接。
谢谢
表“名称”
最近学的单数是正确的
是的。当心异教徒。 表名 中的复数是一个没有阅读任何标准材料并且不了解数据库理论的人的明确标志。
关于标准的一些奇妙之处是:
标准的表名是指表中的每一 行 ,用在所有的措辞中,而不是表的全部内容(我们知道Customer表包含所有客户)。
Customer
关系,动词短语
在已建模的真正关系数据库中(与 1970 年之前的记录归档系统相反 [Record IDs为了方便,其特点是在 SQL 数据库容器中实现):
Record IDs
[图_A][图_A]
当然,关系在 SQL 中实现为CONSTRAINT FOREIGN KEY子表中的一个(更多,稍后)。这是 动词短语 (在模型中)、它表示的 谓词 (从模型中读取)和 FK 约束名称 :
CONSTRAINT FOREIGN KEY
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::product(这不是命名约定问题;这是一个数据库设计问题。)是否为 1::n无关紧要。重要的是是否product是一个单独的实体以及它是否是一个 Independent Table ,即。它可以独立存在。因此product,不是user_product。
user::product
product
user_product
如果product仅存在于 , 的上下文中user。它是一个 从属表 ,因此user_product。
user
[图_B][图_B]
更进一步,如果我(出于某种原因)每个产品都有几个产品描述,它会是“用户产品描述”还是“产品描述”或只是“描述”? 当然,如果设置了正确的外键。仅将其命名为描述将是有问题的,因为我还可以拥有用户描述或帐户描述或其他任何内容。
这是正确的。根据上述情况,异或将是正确的user_product_description。product_description这不是将它与 other 区分开来xxxx_descriptions,而是让名称有一种归属感,前缀是父表。
user_product_description
product_description
xxxx_descriptions
如果我想要一个只有两列的纯关系表(多对多),这会是什么样子? “user-stuff”或者类似“rel-user- stuff”的东西?如果是第一个,它与“用户产品”有何区别?
希望关系数据库中的所有表都是纯关系的规范化表。无需在名称中标识它(否则所有表都将是rel_something)。
rel_something
如果它 仅 包含两个父级的 PK(将在逻辑级别不作为实体存在的 逻辑n::n 关系解析为 物理 表),则为 关联表 。是的,通常该名称是两个父表名称的组合。
[图_C][图_C]
* 如果它 _不是_ 一个关联表(即除了两个 PK 之外,它还包含数据),那么适当地命名它,并且动词短语适用于它,而不是关系末尾的父级。
[图_D][图_D]
你在做什么很重要,它会影响各个层面的易用性和理解。因此,最好在一开始就获得尽可能多的理解。在您开始使用 SQL 编码之前,其中大部分内容的相关性并不清楚。
案例 是要解决的第一个项目。所有大写字母都是不可接受的。大小写混合是正常的,尤其是当用户可以直接访问这些表时。参考我的数据模型。请注意,当搜索者使用一些只有小写字母的疯狂 NonSQL 时,我会给出它,在这种情况下,我会包含下划线(根据您的示例)。
保持 数据焦点 ,而不是应用程序或使用焦点。毕竟是 2011 年,自 1984 年以来我们就有了 开放架构 ,并且数据库应该独立于使用它们的应用程序。
这样,随着它们的增长,并且不止一个应用程序使用它们,命名将保持有意义,并且不需要更正。(完全嵌入单个应用程序的数据库不是数据库。)仅将数据元素命名为数据。
要非常体贴,并且非常 准确地 命名表和列。UpdatedDate如果它是数据类型,请不要使用,请DATETIME使用UpdatedDtm. _description如果它含有剂量,请勿使用。
UpdatedDate
DATETIME
UpdatedDtm
_description
在整个数据库中 保持一致 很重要。不要NumProduct在一个地方使用来表示产品的数量和ItemNo/或ItemNum在另一个地方使用来表示物品的数量。一致地用于NumSomething数量和SomethingNo或SomethingId标识符。
NumProduct
ItemNo
ItemNum
NumSomething
SomethingNo
SomethingId
不要在列名前加上表名或短代码,例如user_first_name. SQL 已经提供了表名作为限定符:
user_first_name
table_name.column_name -- notice the dot
例外:
第一个例外是 PK,它们需要特殊处理,因为您始终在连接中对它们进行编码,并且您希望键从数据列中脱颖而出。一直用user_id,从不id。
user_id
id
请注意,这 不是 用作前缀的表名,而是键组件的正确描述性名称:user_id是标识用户的列,而不是表id的user列。
(user_id, product_no)
AssemblyCode
ComponentCode
PartCodes
PartCode
图_E
REF_用于 Order Entry 集群的参考表 OE_等。
REF_
OE_
仅在物理级别,而不是逻辑级别(它使模型混乱)。
_VView(TableName当然是main在前) _fkForeign Key(约束名,不是列名) _cacCache _segSegment _trTransaction(存储的proc或函数) _fnFunction(非事务性)等
_V
TableName
_fk
_cac
_seg
_tr
_fn
格式是表或 FK 名称、下划线和操作名称、下划线,最后是后缀。
这非常重要,因为当服务器给你一个错误信息时:
____blah blah blah error on object_name
blah blah blah error on object_name
您确切地知道违反了什么对象,以及它试图做什么:
____blah blah blah error on Customer_Add_tr
blah blah blah error on Customer_Add_tr
Customer_Initiates_SalesOrder_fk Part_Comprises_Component_fk Part_IsConsumedIn_Assembly_fk
Customer_Initiates_SalesOrder_fk
Part_Comprises_Component_fk
Part_IsConsumedIn_Assembly_fk
使用Parent_Child_fk顺序,不是Child_Parent_fk因为(a)当您查找它们时它以正确的排序顺序显示,并且(b)我们总是知道所涉及的孩子,我们猜测的是哪个父母。然后错误消息令人愉快:
Parent_Child_fk
Child_Parent_fk
____ Foreign key violation on Vendor_Offers_PartVendor_fk.
Foreign key violation on Vendor_Offers_PartVendor_fk
这对于那些费心为他们的数据建模的人来说效果很好,其中动词短语已经被识别出来。对于其余部分,记录归档系统等使用Parent_Child_fk.
U唯一的,或_用于非唯一的 C集群,或_用于非集群的 _分隔符
U
_
C
对于其余部分: - 如果键是一列或很少几列: ____ColumnNames
ColumnNames
- If the key is more than a few columns:
_PK主键(根据型号) _AK[*n*]备用键(IDEF1X 术语)
PK
AK[*n*]
请注意,索引名称中不需要表名 , 因为它始终显示为table_name.index_name.
table_name.index_name.
因此,当Customer.UC_CustomerId或Product.U__AK出现在错误消息中时,它会告诉您一些有意义的事情。当您查看表格上的索引时,您可以轻松区分它们。
Customer.UC_CustomerId
Product.U__AK
找一个合格和专业的人并跟随他们。查看他们的设计,并仔细研究他们使用的命名约定。向他们询问您不了解的任何具体问题。相反,任何对命名约定或标准漠不关心的人都逃之夭夭。这里有一些可以帮助您入门:
它们包含上述所有内容的真实示例。在此线程中提出问题重命名问题。
****具有符合标准的地址的 订单输入和库存
用于 PHP/MyNonSQL的简单的办公室间 公告系统
****具有完整时间功能的 传感器监控
这无法在评论空间中得到合理的回答。
Larry Lustig: ……即使是最简单的例子也表明…… 如果客户有零对多的产品,而产品有一对多的组件,而组件有一对多的供应商,而供应商的销售量为零多对多组件和销售代表具有一对多客户 保存客户、产品、组件和供应商的表的“自然”名称是什么?
您的评论有两个主要问题:
您声明您的示例是“最微不足道的”,但是,它绝不是。有了这种矛盾,我不确定你是否认真,如果技术上有能力。
这种“微不足道”的推测有几个严重的规范化(数据库设计)错误。
在你纠正之前,它们是不自然的和不正常的,它们没有任何意义。您不妨将它们命名为异常_1、异常_2 等。
您有不提供任何东西的“供应商”;循环引用(非法和不必要的);客户在没有任何商业工具(例如发票或销售订单)的情况下购买产品作为购买的基础(或者客户是否“拥有”产品?);未解决的多对多关系;等等
一旦标准化,并识别出所需的表,它们的名称将变得显而易见。自然。
无论如何,我会尽力为您提供服务。这意味着我将不得不添加一些意义,不知道你的意思,所以请多多包涵。严重错误太多,无法列出,鉴于备用规格,我不确定我是否已全部纠正。
我假设如果产品由组件组成,那么产品就是一个组件,并且组件用于多个组件。
此外,由于“供应商销售零对多组件”,他们 不 销售产品或组件,他们只销售组件。
推测与标准化模型
如果您不知道,方角(独立)和圆角(依赖)之间的区别很大,请参阅 IDEF1X 符号链接。同样,实线(识别)与虚线(非识别)。
… 包含客户、产品、组件和供应商的表的“自然”名称是什么?
现在我已经解决了表格,我不明白你的问题。也许您可以发布一个 特定 的问题。
VoteCoffee: 您如何处理 Ronnis 在他的示例中发布的两个表(user_likes_product、user_bought_product)之间存在多个关系的场景?我可能会误解,但这似乎会导致使用您详细说明的约定导致重复的表名。
假设没有规范化错误,User likes Product是谓词,而不是表。不要混淆他们。请参阅我的回答,它与主语、动词和谓词有关,以及我在上面对拉里的回答。
User likes Product
每个表包含一组事实(每一行 都是 一个事实)。谓词(或命题)不是事实,它们可能是也可能不是真的。
关系模型 基于一阶谓词演算(通常称为一阶逻辑)。谓词是简单、精确的英语中的单句句子,其评估结果为真或假。
此外,每个表都代表或实现了 许多 谓词,而不是一个。
查询是对 Predicate(或多个 Predicate,链接在一起)的测试,结果为 true(事实存在)或 false(事实不存在)。
因此,应该为表命名,如我的答案(命名约定)中详述的那样,对于行、事实和谓词应该记录(无论如何,它是数据库文档的一部分),但作为一个单独的谓词列表.
这并不是说它们不重要。它们非常重要,但我不会在这里写出来。
那么快点。由于 Relational Model 是建立在FOPC之上的,所以整个数据库可以说是一组FOPC声明,一组Predicates。但是 (a) Predicate 的类型很多,并且 (b) 一个表不代表一个 Predicate(它是 许多 Predicates 和不同 类型 Predicates 的物理实现)。
因此,将表命名为“表示”的“该”谓词是一个荒谬的概念。
“理论家”只知道几个谓词,他们不明白,既然 RM 是建立在 FOL 上的,那么整个数据库就是一组谓词,并且是不同类型的。
当然,他们会从他们所知道的少数几个中选择荒谬的EXISTING_PERSON:PERSON_IS_CALLED. 如果不是那么难过,那就太搞笑了。
EXISTING_PERSON
PERSON_IS_CALLED
另请注意,标准或原子表名称(命名行)非常适用于所有措辞(包括附加到表的所有谓词)。相反,愚蠢的“表代表谓词”名称不能。这对“理论家”来说很好,他们对谓词知之甚少,但在其他方面却迟钝。
与数据模型相关的谓词在 模型中表示,它们有两个顺序。
一元谓词 第一组是 图解 的,而不是文字 的:符号本身 。这些包括各种存在;约束导向;和描述符(属性)谓词。
当然,这意味着只有那些能够“读取”标准数据模型的人才能读取这些谓词。这就是为什么被纯文本思维严重削弱的“理论家”无法阅读数据模型,为什么他们坚持 1984 年之前的纯文本思维。
二元谓词 第二组是那些在事实之间形成 关系的谓词。 这是关系线。动词短语(上面详述)标识了已实现的谓词,即 命题(可以通过查询进行测试)。 没有比这更明确的了。
因此,对于精通标准数据模型的人来说,所有 相关 的谓词都记录在模型中。他们不需要单独的谓词列表(但是不能从数据模型中“读取”所有内容的用户可以这样做!)。
这是一个 数据模型 ,我在其中列出了谓词。我选择了那个例子,因为它显示了存在等谓词以及关系谓词,唯一没有列出的谓词是描述符。在这里,由于寻求者的学习水平,我将他视为用户。
因此,两个父表之间存在多个子表的事件是没有问题的,只需将它们命名为Existential Fact re它们的内容,并将名称标准化。
我为关联表的关系名称的动词短语给出的规则在这里发挥了作用。这是一个 谓词与表 的讨论,总结了所有提到的要点。
有关正确使用谓词以及如何使用它们的简短描述(这与此处回复评论的上下文完全不同),请访问 此答案 ,然后向下滚动到 谓词 部分。
Charles Burns: 按顺序,我的意思是Oracle 风格的对象,纯粹用于根据某些规则(例如“加1”)存储一个数字及其下一个数字。由于 Oracle 缺少自动 ID 表,我的典型用途是为表 PK 生成唯一 ID。插入 foo(id, somedata) 值 (foo_s.nextval, “data”…)
好的,这就是我们所说的 Key 或 NextKey 表。如此命名。如果您有 SubjectAreas,请使用 COM_NextKey 指示它在整个数据库中是通用的。
顺便说一句,这是一种非常糟糕的生成密钥的方法。根本没有可扩展性,但是以 Oracle 的性能,它可能“还好”。此外,它表明您的数据库充满了代理项,而不是这些区域的关系。这意味着极差的性能和缺乏完整性。