关系表命名约定
我正在开始一个新项目,希望从一开始就让我的表和列名称。 例如,我总是在表名中使用复数,但最近学到的单数是正确的。
所以,如果我有一个“用户”表,然后我得到的产品,只有用户将有,如果表名为“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”这样的东西? 如果是第一个,那么可以将其与“用户产品”区分开来吗?
-
希望关系数据库中的所有表都是纯关系,规范化表。 没有必要确定名称(否则所有的表都将是
rel_something
)。 -
如果它只包含两个父母的PK(它解决逻辑层次上不存在的作为一个实体的逻辑 n :: n关系到物理表中),那么这是一个关联表 。 是的,通常名称是两个父表名称的组合。
-
请注意,这种情况下,动词短语适用于父母之间,而不是从父母到父母,因为它唯一的目的就是将父母联系起来。
Diagram_C
-
如果它不是一个关联表(即除了两个PK之外,它包含数据),则适当命名它,动词短语适用于它,而不是关系结束时的父母。
Diagram_D
-
-
如果你最终得到两个
user_product
表,那么这是一个非常大的信号,你没有规范化数据。 所以回到几个步骤,并做到这一点,并准确,一致地命名表。 名字将自行解决。
命名约定
任何帮助,高度赞赏,如果有某种forms的命名约定标准那里你们推荐,随意链接。
你所做的事情非常重要,会影响到各个层面的使用和理解。 因此,从一开始就尽可能多地理解。 大部分的相关性不会很清楚,直到你开始在SQL中进行编码。
-
案例是第一个要解决的问题。 所有上限是不可接受的。 混合大小写是正常的,特别是如果用户可以直接访问这些表。 参考我的数据模型。 请注意,当search者使用一些疯狂的NonSQL,只有小写,我给,在这种情况下,我包括下划线(按照您的例子)。
-
保持数据重点 ,而不是应用程序或使用重点。 毕竟,自从1984年以来,我们已经拥有了开放式架构 ,数据库应该独立于使用它们的应用程序。
这样,随着他们的成长,不只一个应用程序使用它们,命名仍然是有意义的,不需要更正。 (完全embedded到单个应用程序中的数据库不是数据库。)仅将数据元素命名为数据。
-
要非常体贴,并且非常准确地命名表格和列。 如果它是
DATETIME
数据types,请不要使用UpdatedDate
,请使用UpdatedDtm
。 如果含有剂量,请勿使用_description
。 -
在整个数据库中保持一致非常重要。 不要在一个地方使用
NumProduct
来表示产品的数量和在另一个地方的NumProduct
或ItemNum
来表示项目的数量。NumSomething
使用NumSomething
作为数字,而SomethingNo
或SomethingId
作为标识符。 -
不要在表名或短代码(如
user_first_name
加上列名。 SQL已经提供了表名作为限定符:table_name.column_name -- notice the dot
-
例外:
-
第一个例外是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
AssemblyCode
和ComponentCode
。 在这种情况下,不要使用无差别的PartCode
。 准确。Diagram_E
-
-
字首
如果您有超过100个表格,则在表格名称的前面添加一个主题区域:参考表的
REF_
订单input群集的OE_
等只有在物理层面上,不是逻辑上的(它使模型变得混乱)。
-
后缀
切勿在表格中使用后缀,并且在其他所有内容上始终使用后缀。 这意味着在数据库的逻辑,正常使用中,没有下划线; 但在行政方面,下划线被用作分隔符:_V
查看(当然,前面的主要TableName
)
_fk
外键(约束名称,而不是列名)
_cac
caching
_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)当你正在寻找它们时它以正确的sorting顺序显示,(b)我们总是知道涉及的孩子,我们猜测的是哪个父母。 错误信息是令人愉快的:____
Foreign key violation on Vendor_Offers_PartVendor_fk
。对于那些懒得模拟数据的人来说,那些动词短语已经被识别出来了。 其余的,logging归档系统等使用
Parent_Child_fk
。 -
指数是特殊的,所以他们有一个自己的命名约定, 按顺序组成 ,从1到3的每个字符位置:
U
唯一或_
非唯一
C
群集,或者_
非群集
_
分隔符其余部分:
-
如果密钥是一列或几列:
____列名 -
如果关键是超过了几列:
____PK
主键(按型号)
____AK[*n*]
备用密钥(IDEF1X术语)
请注意,索引名称中不需要表名,因为它始终显示为
table_name.index_name.
所以当
Customer.UC_CustomerId
或Product.U__AK
出现在错误信息中时,它会告诉你一些有意义的东西。 当您查看表格中的索引时,可以轻松区分它们。 -
-
找一个合格和专业的人,并遵循他们。 看看他们的devise,并研究他们使用的命名约定。 询问他们关于你不了解的任何问题。 反过来说,任何不关心命名约定或标准的人都应该这样做。 这里有几个让你开始:
- 它们包含所有上述的实例。 在这个线程中提出问题重命名问题。
- 当然,除了命名约定之外,这些模型还实现了其他几个标准。 你现在可以忽略这些,或者随时提出具体的新问题 。
- 它们每页都有几页,SO中的内联图像支持是针对鸟类的,而且它们不会在不同浏览器上持续加载; 所以你将不得不点击链接。
- 请注意,PDF文件具有完整的导航,所以点击蓝色的玻璃button或扩展标识的对象:
- 不熟悉关系build模标准的读者可能会发现IDEF1X Notation有帮助。
订单input和库存符合标准的地址
简单的用于PHP / MyNonSQL的办公室间公告系统
传感器监测具有全面的时间能力
问题的答案
这在评论空间中无法合理回答。
Larry Lustig:
…即使是最微不足道的例子显示…
如果一个客户有零对多的产品,一个产品有一对多的组件,一个组件有一对多的供应商,而一个供应商销售零对多的组件,而一个SalesRep拥有一对多的客户什么是持有客户,产品,组件和供应商的“自然”名称?
您的评论有两个主要问题:
-
你声明你的例子是“最微不足道的”,但是,它不是什么。 有了这样的矛盾,我不确定你是否认真,如果技术上有能力的话。
-
这种“微不足道的”猜测有几个总体标准化(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)。 但是,我们可以单数去解答这个问题的答案。
-
既然你可能需要一个表'用户',另一个'产品',第三个用户连接产品,那么你需要一个表'user_product'。
-
由于说明适用于产品,因此您可以使用“product_description”。 除非每个用户自己命名每个产品…
-
“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_t
, tbl_order
, user_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_product
, user_bought_product
, user_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”。