关系表命名约定
我正在开始一个新项目,并想从一开始就让我的表和列名称正确。 例如,我总是在表名中使用复数形式,但最近学到的单数形式是正确的。
那么,如果我得到了一个“用户”表,然后我得到了只有用户才有的产品,那么该表应该被命名为“user_product”还是“产品”? 这是一对多的关系。
更进一步说,如果我有(出于某种原因)每个产品的几个产品描述,它会是“user_product_description”或“product_description”或只是“描述”? 当然,正确的外键设置..命名它只描述会有问题,因为我也可以有用户描述或帐户描述或任何..
如果我想要一个只有两列的纯关系表(多对多),那么这将是什么样子? “user_stuff”还是像“rel_user_stuff”? 如果第一个,可以区分这个,例如“user_product”?
任何帮助,高度赞赏,如果有某种命名约定标准那里你们推荐,随时链接。
谢谢
表•名称
最近学会奇异是正确的
是。 谨防异教徒。 表格名称中的多个字符是没有阅读过任何标准材料并且没有数据库理论知识的人的明确标志。
关于标准的一些美妙的事情是:它们全部相互结合; 他们一起工作; 而且他们的写作思想比我们的更大,所以我们不必辩论它们。 标准表名称是指表中的每一行 ,用于所有语言,而不是表格的全部内容(我们知道Customer
表包含所有客户)。
关系,动词短语
在已经建模的真正的关系数据库中(与在SQL数据库容器中实现的记录归档系统相反):
Diagram_A
当然,这种关系在SQL中作为子表中的外键约束实现(更多,稍后)。 这里是动词短语 (在模型中),它表示的谓词 (要从模型中读取)以及FK 约束名称 :
Initiates
Each Customer Initiates 0-to-n SalesOrders
Customer_Initiates_SalesOrder_fk
表•语言
但是,在描述表格时,特别是在Predicates等技术语言或其他文档中,使用单数形式和复数形式,因为它们在英语语言中很自然。 请记住,表格是为单行(关系)命名的,而语言是指每个派生行(派生关系):
Each Customer initiates zero-to-many SalesOrders
不
Customers have zero-to-many SalesOrders
那么,如果我得到了一个“用户”表,然后我得到了只有用户才有的产品,那么该表应该被命名为“用户产品”还是“产品”? 这是一对多的关系。
(这不是一个命名约定的问题,这是一个数据库设计问题。) user::product
是否为1 :: n并不重要。 重要的是product
是否是一个独立的实体,以及它是否是一个独立表 ,即。 它可以独立存在。 因此product
,而不是user_product
。
如果product
仅存在于user
的上下文中,即。 它是一个从属表 ,因此user_product
。
Diagram_B
更进一步说,如果我有(出于某种原因)每种产品的几种产品说明,它会是“用户产品说明”还是“产品说明”或只是“说明”? 当然,正确的外键设置..命名它只描述会有问题,因为我也可以有用户描述或帐户描述或其他。
那就对了。 根据以上所述, user_product_description
xor product_description
将是正确的。 这不是要将它与其他xxxx_descriptions
,而是要为名称xxxx_descriptions
它所属的位置,前缀是父表的名称。
如果我想要一个只有两列的纯关系表(多对多),那么这将是什么样子? “用户东西”,或者像“rel-user-stuff”这样的东西? 如果是第一个,那么可以将它与“用户产品”区分开来?
希望关系数据库中的所有表都是纯关系,规范化表。 没有必要在名称中标识(否则所有表都将是rel_something
)。
如果它仅包含两个亲本的PK(它解决了逻辑Ñ:: N的关系并不作为一个实体在逻辑层的存在,为物理表),这是一个关联表 。 是的,通常名称是两个父表名称的组合。
请注意,在这种情况下,动词短语适用于父母,因此它被忽略了子表,因为它唯一的目的就是将两个父母联系起来。
Diagram_C
如果它不是关联表(即除两个PK之外,它包含数据),则适当命名它,动词短语适用于它,而不是关系末尾的父母。
Diagram_D
如果最终有两个user_product
表,那么这是一个非常响亮的信号,表示您没有对数据进行标准化。 所以,回过头几步就可以做到这一点,并且准确而一致地命名表格。 名字将自行解决。
命名约定
任何帮助,高度赞赏,如果有某种命名约定标准那里你们推荐,随时链接。
你在做什么是非常重要的,它会影响到每个级别的易用性和理解性。 因此,从一开始就尽可能多地理解。 大部分内容的相关性不会很清楚,除非您开始使用SQL进行编码。
案例是第一个要解决的问题。 所有上限都是不可接受的。 混合大小写是正常的,特别是如果用户可以直接访问这些表。 参考我的数据模型。 请注意,当搜索者使用一些只有小写字母的疯狂NonSQL时,我会给出这种情况,在这种情况下,我会包含下划线(按照您的示例)。
保持数据重点 ,而不是应用程序或使用重点。 毕竟,自从1984年以来,我们拥有开放式架构 ,并且数据库应该独立于使用它们的应用程序。
这样,随着它们的增长,以及超过一个应用程序使用它们,命名仍然有意义,并且不需要更正。 (完全嵌入到单个应用程序中的数据库不是数据库。)仅将数据元素命名为数据。
要非常体贴,并且非常准确地命名表格和列。 如果它是DATETIME
数据类型,请不要使用UpdatedDate
,请使用UpdatedDtm
。 如果含有剂量,请勿使用_description
。
在整个数据库中保持一致非常重要。 不要使用NumProduct
在一个地方来指示产品和数量ItemNo
或ItemNum
在另一个地方,表示项目的数量。 NumSomething
将NumSomething
用于数字 - 和SomethingNo
或SomethingId
以用于标识符。
不要在列名user_first_name
加上表名或短代码,如user_first_name
。 SQL已经提供了表名作为限定符:
table_name.column_name -- notice the dot
例外:
第一个例外是PK,它们需要特殊的处理,因为你始终在连接中对它们进行编码,并且你希望密钥从数据列中脱颖而出。 始终使用user_id
,永远不会使用id
。
user_id
是标识用户的列,而不是user
表的id
。 user_product
表将具有一个user_id
作为其PK (user_id, product_no)
。 id
,很容易混淆在SQL编码中。 其次,初始编码人员不知道他在做什么。 如果按照上述方式处理关键列,那么这两者都很容易防止。 第二个例外是引用同一父表的多个FK引用的子节点。 根据关系模型,使用角色名称来区分含义或用法,例如。 两个PartCodes
AssemblyCode
和ComponentCode
。 而在这种情况下, 不使用未分化PartCode
为其中之一。 准确。
Diagram_E
字首
如果您有超过100个表格,请在表格名称前加上一个主题区域:
参考表的REF_
订单输入群集的OE_
等
只有在物理层面上,不是逻辑上的(它使模型变得混乱)。
后缀
切勿在表格上使用后缀,并且在其他所有内容上始终使用后缀。 这意味着在数据库的逻辑,正常使用中,不存在下划线; 但在行政方面,下划线用作分隔符:
_V
视图(当然,前面的主要TableName
)
_fk
外键(约束名称,而不是列名称)
_cac
缓存
_seg
细分
_tr
事务(存储过程或函数)
_fn
函数(非事务性)等
格式是表格或FK名称,下划线和操作名称,下划线,最后是后缀。
这非常重要,因为当服务器给你一个错误信息时:
____ blah blah blah error on object_name
你确切地知道什么对象被侵犯,以及它试图做什么:
____ blah blah blah error on Customer_Add_tr
外键 (约束,而不是列)。 FK的最佳命名是使用动词短语(减去“每个”和基数)。
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到3中的每个字符位置组成:
U
唯一,或者_
表示非唯一
C
群集,或者_
非群集
_
分隔符
其余部分:
如果密钥是一列或几列:
____ ColumnNames
如果密钥超过几列:
____ PK
主键(按照型号)
____ AK[*n*]
备用密钥(IDEF1X任期)
请注意,索引名称中不需要表名,因为它始终显示为table_name.index_name.
因此,当Customer.UC_CustomerId
或Product.U__AK
出现在错误消息中时,它会告诉您一些有意义的内容。 当您查看表格中的索引时,可以轻松区分它们。
找一个合格和专业的人,并遵循他们。 看看他们的设计,并研究他们使用的命名约定。 询问他们关于你不了解的任何问题的具体问题。 相反,如果没有人关心命名约定或标准,就像地狱一样。 这里有几个让你开始:
订单输入和库存符合标准的地址
简单的用于PHP / MyNonSQL的局间公告系统
具有全时间功能的传感器监测
问题的答案
这在评论空间中无法合理回答。
Larry Lustig:
...即使是最微不足道的例子显示...
如果客户具有零对多产品,并且产品具有一对多组件,并且组件具有一对多供应商,而供应商销售零对多组件并且SalesRep拥有一对多客户什么是持有客户,产品,组件和供应商的“自然”名称?
您的评论中有两个主要问题:
你声明你的例子是“最微不足道的”,但是,它不是什么。 由于这种矛盾,如果技术能力很强,我不确定你是否认真。
这种“微不足道的”猜测有几个总体标准化(DB Design)错误。
在你纠正这些之前,他们是不自然和不正常的,他们没有任何意义。 你不妨将它们命名为abnormal_1,abnormal_2等。
你有“供应商”谁不提供任何东西; 循环引用(非法,不必要); 客户购买没有任何商业工具(如发票或销售订单)的产品作为购买的基础(或者做客户“自己”的产品?); 未解决的多对多关系; 等等
一旦这是规范化,并确定所需的表格,他们的名字将变得明显。 自然。
无论如何,我会尽力为您的查询提供服务。 这意味着我将不得不增加一些意识,不知道你的意思,所以请耐心等待。 严重的错误太多,无法列出,并给予了备用规格,我不相信我已经纠正了他们。
我将假设如果产品是由组件组成的,那么产品就是一个组件,并且这些组件被用在多个组件中。
此外,由于“供应商销售零对多组件”,他们不销售产品或组件,他们只销售组件。
投机与规范化模型
如果您不知道,方角(独立)和圆角(从属)之间的差异很大,请参阅IDEF1X表示法链接。 同样的实线(识别)与虚线(非识别)。
...什么是持有客户,产品,组件和供应商的“自然”名称?
现在我已经解决了表格,我不明白你的问题。 也许你可以发表一个具体的问题。
VoteCoffee:
你如何处理Ronnis在他的例子中发表的两个表格(user_likes_product,user_bought_product)之间存在多重关系的情景? 我可能会误解,但是这似乎会导致使用您详述的约定重复表名。
假设没有规范化错误, User likes Product
是谓词,而不是表格。 不要混淆他们。 参考我的答案,它涉及到主语,动词和谓语,以及我对上面拉里的回应。
每个表格都包含一组事实(每一行都是事实),而不是谓词。 谓词(或命题)不是事实,它们可能或可能不是真实的。
查询是对谓词(或一系列谓词链接在一起)的测试,其结果为真(事实存在)或假(事实不存在)。
因此,应按照我的Answer(命名约定)中详细说明的那样对表进行命名,对于行,事实和谓词应该进行记录(无论如何,它都是数据库文档的一部分),但作为Predicates的单独列表。
这并不意味着他们并不重要。 他们非常重要,但我不会在这里写出来。
那么快速。 由于关系模型建立在FOL上,因此整个数据库可以说是一组声明,一组谓词。 但是,(一)有很多类型的谓词,和(b)的表不代表谓词(它是许多谓词的物理实现,以及不同类型的谓词的)。
因此,将表格命名为“它”所代表的谓词是荒谬的概念。
“理论家”只知道少数谓词,他们不明白自从RM建立在FOL之后,整个数据库就是一组谓词和不同类型。
当然,他们从他们所知道的少数人中选择荒谬的:EXISTING_PERSON; PERSON_IS_CALLED。 如果它不那么难过,那会很搞笑。
还要注意,标准或原子表名(命名行)对于所有的语言(包括附在表格中的所有谓词)都表现出色。 相反,愚蠢的“表格代表谓语”的名字不能。 这对于“理论家”来说很好,他们对于谓词的理解很少,但是否则就会受到阻碍。
是相关的数据模型的谓词, 在模型中表示,他们有两种。
第一套是图表,而不是文字,形式:符号。 这些包括各种存在主义; 约束为导向的; 和描述符(属性)谓词。
当然,这意味着只有那些可以“读取”标准数据模型的人才能阅读这些谓词。 这就是为什么那些被纯文本思维严重摧残的“理论家”无法读取数据模型,为什么他们坚持1984年以前的纯文本思维模式。
第二组是那些形成事实之间关系的谓词。 这是关系线。 动词短语(详述如上)标识已经实施的谓词(可以通过查询来测试)。 没有比这更明确的了。
因此,对于精通标准数据模型的人员,所有相关的谓词都记录在模型中。 他们不需要单独的Predicates列表(但用户可以!)。
这是一个数据模型 ,我列出了谓词。 我选择了这个例子,因为它显示了存在主义等,谓词以及关系,唯一没有列出的谓词是描述符。 在这里,由于探索者的学习水平,我将他视为一个用户。
因此,两个父表之间的多个子表的事件不是问题,只需将它们命名为Existential Fact来表示它们的内容,并对这些名称进行规范化。
我在这里使用了关于关联表关系名称的动词短语的规则。 这里是一个Predicate vs Table的讨论,总结了所有提到的要点。
对于一个很好的简短描述,重新使用Predicates以及如何使用它们(这与在此处回应评论的背景完全不同),请访问此答案并向下滚动到Predicate部分。
查尔斯伯恩斯:
按顺序,我指的是纯粹用于存储数字的Oracle风格对象,根据某些规则(例如“加1”)存储数字。 由于Oracle缺少自动ID表,因此我的典型用法是为表PK生成唯一的ID。 INSERT INTO foo(id,somedata)VALUES(foo_s.nextval,“data”...)
好的,这就是我们所说的Key或NextKey表。 这样命名。 如果您有SubjectAreas,请使用COM_NextKey指示它在整个数据库中是通用的。
顺便说一句,这是一个非常糟糕的方法来生成密钥。 根本不可扩展,但随着Oracle的表现,它可能“很好”。 此外,它表明您的数据库充满了代理,而不是这些区域的关系。 这意味着性能极差,缺乏完整性。
奇异与复数:挑一个并坚持下去。
列不应该加上前缀/后缀/加入,或者反过来固定参考它是列的事实。 表格也是一样。 不要命名表EMPLOYEE_T或TBL_EMPLOYEES,因为第二个被替换为视图,事情变得非常混乱。
不要在名称中嵌入类型信息,例如varchar的“vc_firstname”或“flavour_enum”。 也不要在列名中嵌入约束,例如“department_fk”或“employee_pk”。
实际上,我能想到的关于*修复的唯一好处是可以使用保留字如where_t
, tbl_order
, user_vw
。 当然,在这些例子中,使用复数将解决问题:)
不要将所有密钥命名为“ID”。 引用同一事物的键应在所有表中具有相同的名称。 用户标识列可以在用户表和所有引用用户的表中被称为USER_ID。 重命名的唯一时间是不同的用户正在扮演不同的角色,例如Message(sender_user_id,receiver_user_id)。 这在处理较大的查询时确实有帮助。
关于CaSe:
thisiswhatithinkofalllowercapscolumnnames.
ALLUPPERCAPSISNOTBETTERBECAUSEITFEELSLIKESOMEONEISSCREAMINGATME.
CamelCaseIsMarginallyBetterButItStillTakesTimeToParse.
i_recommend_sticking_with_lower_case_and_underscore
一般来说,最好命名“映射表”以匹配它描述的关系,而不是引用表的名称。 用户可以与产品有任何数量的关系: user_likes_product
, user_bought_product
, user_wants_to_buy_product
。
关于单数还是复数,没有“正确” - 这主要是品味的问题。
这部分取决于你的关注点。 如果您将表格视为一个单位,它将包含'复数'(因为它包含许多行 - 所以复数名称是适当的)。 如果您将表格名称视为标识表格中的某一行,则您更喜欢“单数”。 这意味着你的SQL将被认为是在表中的一行上工作。 没关系,虽然它通常是过分简单化的; SQL在集合上工作(或多或少)。 但是,我们可以用单数来解答这个问题的答案。
既然你可能需要一个表'用户',另一个'产品',第三个用户连接产品,那么你需要一个表'user_product'。
由于说明适用于产品,因此您可以使用'product_description'。 除非每个用户为自己命名每个产品...
'user_product'表是(或可能是)带有产品ID和用户ID的表格的示例,而不是其他。 用同样的通用方式命名两个属性表:'user_stuff'。 像'rel_'这样的装饰性前缀并没有真正的帮助。 例如,您会看到一些人在每个表名前面使用't_'。 这不是很多帮助。
上一篇: Relational table naming convention
下一篇: Is storing a delimited list in a database column really that bad?