我想知道人们对数据库表中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那么显然是什么表它开着?
关于这个话题的其他人的想法是什么?
我总是首选ID为TableName + ID为id列,然后是TableName + ID为外键.这样,所有表都具有id字段的相同名称,并且没有冗余描述.这对我来说似乎更简单,因为所有表都具有相同的主键字段名称.
至于连接表,不知道哪个ID字段属于哪个表,在我看来,查询应该被写入处理这种情况.在我工作的地方,我们总是优先使用表/表别名在语句中使用的字段.
最近在我的公司里,这是关于这件事的书呆子.LINQ的出现使得冗余的tablename + ID模式在我眼中显得更加愚蠢.我认为大多数合理的人会说,如果你手工编写SQL,你必须指定表名来区分FK,那么它不仅可以节省打字,而且可以增加你的SQL使用的清晰度你可以清楚地看到哪个是PK,哪个是FK.
例如
来自员工e LEFT JOIN客户c ON e.ID = c.EmployeeID
不仅告诉我这两个是联系的,而且是PK,哪个是FK.然而,在旧式中你不得不看起来或希望它们被命名为好.
我们使用InvoiceID
,而不是ID
.它使查询更具可读性 - 当你ID
单独看时它可能意味着什么,特别是当你将表别名时i
.
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字段,那么这种意外错误就不太可能发生并且更容易找到.
我同意Keven和其他一些人的观点,表格的PK应该只是Id而外键列出了OtherTable + Id.
但是,我想补充一个最近给这一论点更重要的理由.
在我目前的职位上,我们正在使用POCO生成的实体框架.使用Id的标准命名约定,PK允许继承具有验证的基础poco类,例如对于共享一组公共列名的表.使用Tablename + Id作为每个表的PK会破坏为这些表使用基类的能力.
只是一些值得思考的东西.
这并不重要,您可能会遇到所有命名约定中的simalar问题.
但是保持一致非常重要,因此每次编写查询时都不必查看表定义.
我的偏好也是主键的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通常是一个糟糕的选择.
我刚开始在一个只使用"ID"的地方工作(在核心表中,在外键中由TableNameID引用),并且已经发现了由它直接引起的两个生产问题.
在一种情况下,查询使用"...其中ID为(SELECT ID FROM OtherTable ..."而不是"...其中ID为(SELECT TransID FROM OtherTable ...").
任何人都可以诚实地说,如果使用完整,一致的名称,那么错误的陈述会读到"......其中TransID in(SELECT OtherTableID from OtherTable ......"?)我不认为这样会更容易发现吗?我不认为所以.
重构代码时会出现另一个问题.如果您使用临时表,而以前查询从核心表中删除,则旧代码读取"... dbo.MyFunction(t.ID)...",如果没有更改,但"t"现在指的是临时表而不是核心表,你甚至没有得到错误 - 只是错误的结果.
如果产生不必要的错误是一个目标(也许有些人没有足够的工作?),那么这种命名约定很棒.否则,一致的命名是要走的路.
为简单起见,大多数人将表名称列在表ID上.如果有另一个表的外键引用,那么他们明确地调用它InvoiceID(使用你的例子)的情况下连接,你是走样表反正这么明确inv.ID仍比inv.InvoiceID简单
我个人比较喜欢(因为已经如上所述)的Table.ID的PK和表格ID为FK。甚至(请不要射击我)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的操作。当然,它会更大一些,但至少,人们不会试图查找表ManagerID或EmployeeID在这里做什么。当查询在哪里时,我可以将其简化为:SELECT EmployeeID_Manager作为ManagerID FROM Store