当前位置:  开发笔记 > 编程语言 > 正文

数据库表中ID列的命名

如何解决《数据库表中ID列的命名》经验,为你挑选了10个好方法。

我想知道人们对数据库表中ID列命名的看法.

如果我有一个名为Invoices的表,其中包含一个标识列的主键,我会调用该列InvoiceID,这样我就不会与其他表发生冲突,而且它显然是什么.

我工作的当前他们已经调用了所有ID列ID.

所以他们会做以下事情:

Select  
    i.ID 
,   il.ID 
From
    Invoices i
    Left Join InvoiceLines il
        on i.ID = il.InvoiceID

现在,我在这里看到一些问题:
1.你需要在select
2 上对列进行别名.ID = InvoiceID不适合我的大脑
3.如果你没有别名表并且提到InvoiceID那么显然是什么表它开着?

关于这个话题的其他人的想法是什么?



1> kemiller2002..:

我总是首选ID为TableName + ID为id列,然后是TableName + ID为外键.这样,所有表都具有id字段的相同名称,并且没有冗余描述.这对我来说似乎更简单,因为所有表都具有相同的主键字段名称.

至于连接表,不知道哪个ID字段属于哪个表,在我看来,查询应该被写入处理这种情况.在我工作的地方,我们总是优先使用表/表别名在语句中使用的字段.


我意识到有一个老话题,但我同意。这也使在数据访问层的映射更加容易:如果所有“对象”都有一个ID字段,该ID字段必须唯一,那么当在数据访问层使方法执行删除项之类的操作时,可以将它们设为通用,因为您可以接收到任何东西的ID都知道,您只需要从该特定表中删除Id = blah,而不必保留每个表的唯一映射以及表名/程序逻辑名映射。
这是我的偏好.仅仅因为跨表查询更难以阅读并不意味着应该更改Id列以使其更容易.只需使您的别名更具描述性.

2> Echostorm..:

最近在我的公司里,这是关于这件事的书呆子.LINQ的出现使得冗余的tablename + ID模式在我眼中显得更加愚蠢.我认为大多数合理的人会说,如果你手工编写SQL,你必须指定表名来区分FK,那么它不仅可以节省打字,而且可以增加你的SQL使用的清晰度你可以清楚地看到哪个是PK,哪个是FK.

例如

来自员工e LEFT JOIN客户c ON e.ID = c.EmployeeID

不仅告诉我这两个是联系的,而且是PK,哪个是FK.然而,在旧式中你不得不看起来或希望它们被命名为好.


人们(例如编写非常复杂的sql的报告编写者)和执行导入和导出的BI专家仍然需要手写SQl.数据库设计也必须容纳它们,而不仅仅是应用程序开发人员.
除了我一生中从未认识过一个开发人员来编写您的示例。他们改为:LEFT JOIN客户为c ON e.ID = c.EmployeeID对我来说,这更清楚了:LEFT JOIN客户为c ON e.EmployeeID = c.EmployeeID哪个项目是外键,通过表名是显而易见的。显然,customer.employeeId是外键,而employee.employeeId不是。

3> Jason Cohen..:

我们使用InvoiceID,而不是ID.它使查询更具可读性 - 当你ID单独看时它可能意味着什么,特别是当你将表别名时i.


使用ID更合适。该列在“发票”表中,因此应该足够了。如果要编写跨表查询,则应使用更具描述性的别名。“ i”是不够的。称其为“发票”。

4> HLGEM..:

ID是SQL Antipattern.请参阅http://www.amazon.com/s/ref=nb_sb_ss_i_1_5?url=search-alias%3Dstripbooks&field-keywords=sql+antipatterns&sprefix=sql+a

如果您有许多ID为ID的表,那么您报告的难度就会大得多.它模糊了含义并使复杂查询更难以阅读,并要求您使用别名来区分报表本身.

此外,如果有人愚蠢到在可用的数据库中使用自然连接,您将加入错误的记录.

如果您想使用某些dbs允许的USING语法,则不能使用ID.

如果您正在使用ID,那么如果您正在复制连接语法(不要告诉我没有人这样做!)并且忘记更改连接条件中的别名,则很容易就会出现错误连接.

所以你现在拥有

select t1.field1, t2.field2, t3.field3
from table1 t1 
join table2 t2 on t1.id = t2.table1id
join table3 t3 on t1.id = t3.table2id

当你的意思

select t1.field1, t2.field2, t3.field3 
from table1 t1 
join table2 t2 on t1.id = t2.table1id
join table3 t3 on t2.id = t3.table2id

如果你使用tablenameID作为id字段,那么这种意外错误就不太可能发生并且更容易找到.


我不喜欢这个约定,因为它只是意味着你实际上被迫为所有表添加别名,这样你就不会冗余地命名表,再次命名表,然后添加id.`在table1.table1id = table2.table1id`上连接table2.你的推理是正确的,除非你使用id,表的名字无论如何都在ID的前面.`在table1.id = table2.table1id`上连接table2 ...这同样冗长而不冗余,也没有强制模糊别名来阻止刚刚提到的冗余..在我看来这是sql开发的祸根.
那么,如果表中有一个`Name`字段,是否应该将其更改为`Table1Name`以避免该字段出现同样的问题?出于同样的原因,您是否应该使用表名称为所有列添加前缀?这听起来不对.
没有!这是smurf命名约定!
@ spencer7593,只是因为你喜欢ID并不意味着它不是反模式.当你拥有tablename id时,很难在连接中出错,因为你会立即得到语法错误.
+1同义词列应该具有相同的名称 - 通过使用表名前缀,您可以拥有一个名为table1ID的主键列和另一个名为table1ID的表中的外键列 - 并且您知道它们是相同的.20年前,我接受了这种教学,这种做法不会让你失望.
我相信@Ross从http://www.codinghorror.com/blog/2012/07/new-programming-jargon.html获得了这一点,而这又是由@ sal提供的(http://stackoverflow.com/users/13753/sal)但我认为它不是在这种情况下 - 你不是为所有东西添加前缀,只是ID字段,在不同的表之间你有不同的前缀.

5> 小智..:

我同意Keven和其他一些人的观点,表格的PK应该只是Id而外键列出了OtherTable + Id.

但是,我想补充一个最近给这一论点更重要的理由.

在我目前的职位上,我们正在使用POCO生成的实体框架.使用Id的标准命名约定,PK允许继承具有验证的基础poco类,例如对于共享一组公共列名的表.使用Tablename + Id作为每个表的PK会破坏为这些表使用基类的能力.

只是一些值得思考的东西.


对于通用命名如何在特定情况下改进代码重用的现实世界示例+1(许多开发人员会关心,因为有数百万个.NET开发人员,而且许多人将使用EF).

6> Nir..:

这并不重要,您可能会遇到所有命名约定中的simalar问题.

但是保持一致非常重要,因此每次编写查询时都不必查看表定义.



7> bjdodo..:

我的偏好也是主键的ID和外键的TableNameID.我还想在大多数表中都有一个列"name",其中我保存了条目的用户可读标识符(即名称:-)).这种结构在应用程序本身提供了极大的灵活性,我可以以相同的方式处理大量表格.这是一个非常强大的东西.通常,OO软件构建在数据库之上,但是由于db本身不允许,因此无法应用OO工具集.列id和名称仍然不是很好,但它是一个步骤.

选择
i.ID,il.ID从发票i左加入InvoiceLines il on i.ID = il.InvoiceID

为什么我不能这样做?

Select  
    Invoices.ID 
,   InvoiceLines.ID 
From
    Invoices
    Left Join InvoiceLines
        on Invoices.ID = InvoiceLines.InvoiceID

在我看来,这非常简单易读.将变量命名为i和il通常是一个糟糕的选择.



8> 小智..:

我刚开始在一个只使用"ID"的地方工作(在核心表中,在外键中由TableNameID引用),并且已经发现了由它直接引起的两个生产问题.

在一种情况下,查询使用"...其中ID为(SELECT ID FROM OtherTable ..."而不是"...其中ID为(SELECT TransID FROM OtherTable ...").

任何人都可以诚实地说,如果使用完整,一致的名称,那么错误的陈述会读到"......其中TransID in(SELECT OtherTableID from OtherTable ......"?)我不认为这样会更容易发现吗?我不认为所以.

重构代码时会出现另一个问题.如果您使用临时表,而以前查询从核心表中删除,则旧代码读取"... dbo.MyFunction(t.ID)...",如果没有更改,但"t"现在指的是临时表而不是核心表,你甚至没有得到错误 - 只是错误的结果.

如果产生不必要的错误是一个目标(也许有些人没有足够的工作?),那么这种命名约定很棒.否则,一致的命名是要走的路.


+1用于提高可维护性的更具体名称的真实世界示例.

9> Michael Brow..:

为简单起见,大多数人将表名称列在表ID上.如果有另一个表的外键引用,那么他们明确地调用它InvoiceID(使用你的例子)的情况下连接,你是走样表反正这么明确inv.ID仍比inv.InvoiceID简单



10> percebus..:

个人比较喜欢(因为已经如上所述)的Table.IDPK表格IDFK。甚至(请不要射击我)Microsoft Access都建议这样做。

但是,我也知道一些生成工具偏爱PK的TableID的事实,因为它们倾向于链接单词中包含“ ID”的所有列名,包括ID!

甚至查询设计器也在Microsoft SQL Server上执行此操作(对于您创建的每个查询,您最终都会在列ID的所有表上剥夺所有不必要的新创建的关系)

尽管我的内部OCD讨厌它,但我还是遵循TableID约定。让我们记住,这就是所谓的数据基础,因为这将是希望很多很多很多的应用程序来的基础。并且所有技术都应该受益于规范化,描述清晰的架构。

不用说,当人们开始使用TableName,TableDescription等时,我确实会划清界限。我认为,约定应执行以下操作:

表名称:复数。例如 雇员

表别名:全表名,单数。例如

SELECT Employee.*, eMail.Address
FROM Employees AS Employee LEFT JOIN eMails as eMail on Employee.eMailID = eMail.eMailID -- I would sure like it to just have the eMail.ID here.... but oh well

[更新]

另外,由于“某种关系”或角色,此线程中有一些关于重复列的有效帖子。例如,如果商店有一个EmployeeID,那就告诉我蹲下。所以有时我会做类似Store.EmployeeID_Manager的操作。当然,它会更大一些,但至少,人们不会试图查找表ManagerIDEmployeeID在这里做什么。当查询在哪里时,我可以将其简化为:SELECT EmployeeID_Manager作为ManagerID FROM Store

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有