我的t-sql老师告诉我们,命名PK列“ Id”被认为是不好的做法,没有任何进一步的解释。

为什么命名表PK列“ Id”被认为是不良做法?

评论

好吧,它实际上不是描述,Id表示“身份”,这很容易解释。那是我的看法。

我确定有很多商店都使用Id作为PK名称。我个人使用TableId作为我的命名约定,但我不会告诉任何人其唯一的方法。听起来您的老师只是在尝试表达自己的观点,并将其作为被广泛接受的最佳实践。

绝对可以,不好的做法的类型。关键是要保持一致。如果您使用id,请在各处使用它或不使用它。

您有一个表格...它叫People,有一个列称为Id,您认为Id是什么?一辆车?一条船? ...不,这是人民编号。我认为这不是一个坏习惯,除了Id之外,也不必为PK列命名。

因此,老师在班上走上前告诉你,这是一个没有单独原因的不好的习惯吗?对于老师来说,这是更糟糕的做法。

#1 楼

我要说出来:这并不是一个坏习惯(即使是这样,也没有那么糟糕)。

您可以提出一个论点(如Chad所指出的):它可以掩盖类似以下查询中的错误:

SELECT * 
    FROM cars car
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId


,但是可以通过不为表名使用微小的别名来轻松缓解:

SELECT * 
    FROM cars
    JOIN manufacturer
        ON manufacturer.Id = cars.ManufacturerId
    JOIN models
        ON models.Id = cars.ModelId
    JOIN colors
        ON manufacturer.Id = cars.ColorId


始终使用3字母缩写的做法对我而言似乎比使用列名称id更糟。 (要点:谁实际上将表名cars缩写为car?这是什么目的?)

要点是:保持一致。如果您的公司使用Id,并且您通常会出现上述错误,那么请养成使用完整表名的习惯。如果您的公司禁止使用Id列,请大步走,并使用他们喜欢的任何命名约定。

重点学习实际上是不良做法(例如,多个嵌套的相关子查询)的事物,而不是反复研究这样的问题。命名列“ ID”的问题更像是一种习惯问题,而不是一种不好的做法。


编者注:此查询中的错误是故意的并被用来提出观点。编辑前请先阅读完整答案。

评论


@Chad,它引用了这样一个事实:在该特定查询中,即使没有任何意义,您也使用3个字母作为表名的别名(汽车->汽车。感谢上帝,您省了我的手指)。不要读得太深。

–riwalk
2011-10-17 17:32



比我的别名更糟糕的是,我混合使用了多辆汽车和制造商。一个是复数,另一个不是。如果人们想选择数据库,那是应该选择的错误做法。

–CaffGeek
2011-10-17 17:34



我认为这是不好的做法。显然,就不好的做法而言,这并不可怕..但是却很容易避免,为什么不这样做呢?现在,我同意,对于入门班来说,这是重点吗?可能不会....

–user606723
2011-10-17 19:41



@ user606723,实际上,我认为对于入门类来说,这一点很重要。教授最佳实践应该是基础。除非您有经验,否则您不了解后果,权衡取舍以及何时应偏离最佳做法。

–CaffGeek
2011-10-17 19:53

@乍得,同意不同意。试图教给学生“最佳实践”而不让他们理解为什么是最佳实践是徒劳的。而且,由于您无法涵盖所有​​内容,因此从教授的角度出发,用“您不应该这样做,以后再找出原因”来掩饰这一点是相当明智的选择。好奇的学生可以在这里发布或希望找到已经回答的问题。 (或下课后询问)

–user606723
2011-10-17 20:01



#2 楼

因为当您有一个带有外键的表时,您不能将该外键命名为“ Id”。您将其表名称命名为TableId

,然后您的联接看起来像

SELECT * FROM cars c JOIN manufacturer m ON m.Id = c.ManufacturerId


理想情况下,每个条件的条件名称应具有相同的字段名称边

SELECT * FROM cars c JOIN manufacturer m ON m.ManufacturerId = c.ManufacturerId


因此,虽然将ID命名为ManufacturerId似乎是多余的,但随着错误变得明显,在连接条件中出现错误的可能性也就较小。 />
这似乎很简单,但是当您连接多个表时,很可能会出错,请在下面找到一个表...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId


虽然命名正确,但错误仍然存​​在...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.ManufacturerId = car.ManufacturerId
    JOIN models mod
        ON mod.ModelId = car.ModelId
    JOIN colors col
        ON mfg.ManufacturerId = car.ColorId


命名它们ID的另一个原因是“不好的”是,当您从几个查询信息时表,您将需要重命名ID列,以便您可以区分它们。

SELECT   manufacturer.Id as 'ManufacturerId'
        ,cars.Id as 'CarId'
        --etc
    FROM cars 
    JOIN manufacturer
        ON manufacturer.Id = cars.Id


使用准确的名称,这不再是一个问题

评论


不确定这对我来说是否足够好。选择SELECT * FROM cars c JOIN制造商m ON Manufacturer.Id = c.ManufacturerId没错。我已经使用id多年了,却从未发现您描述的是一个真正的问题。

–riwalk
2011-10-17 16:56



我会说,这里的不良做法是为表加上别名,例如mfg或mod。 Manufacturers.id = cars.manufacturer_id可读性很强,该错误也很明显。

–deadalnix
2011年10月17日下午16:59

@Chad>我已经遇到了哑变量名称的问题。多次。对于记录,这里我要对在我的团队中做到这一点的开发人员说的“制造商并不意味着制造商,这意味着您要键入制造商”。

–deadalnix
2011年10月17日17:12

@ Stargazer712:从2个表中进行SELECT *会得到2个ID列。 ID现在不明确:您是按序数还是名称进行引用? SELECT *也不是一个好习惯。可怜的争论。易碎的代码。乍得是正确的:基本上是防御性编码

– gbn
2011-10-17 18:23



@gbn再次重申,如果您仅执行SELECT Manufacturer.id FROM...。所有歧义都将消失,由于id引起的每一个困难都可以很容易地克服,这只是一个问题。

–riwalk
2011年10月17日19:25

#3 楼

默认情况下,Ruby的ActiveRecord库和Groovy的GORM使用“ id”作为代理键。我喜欢这种做法。在每个列名中复制表名是多余的,写起来很繁琐,读起来也很繁琐。

评论


+1表示“阅读起来更加繁琐”。 -命名约定不应被视为草率代码的创可贴,而应将提高可读性作为主要考虑因素。

– ocodo
2011-10-18 1:30



ID阅读起来很繁琐

–HLGEM
11-10-18在20:20

@HLGEM:总是可以用表名来限定列名。

–kevin cline
2011年10月20日21:10

除了阅读比较繁琐之外,我同意。实际上,我更喜欢阅读更具描述性的列名,而花更少的时间弄清楚该列的实际用途。

–德文·迪克森(Devin Dixon)
13年3月20日在20:41

+1,讨厌看到带有诸如Posts.postID,Posts.postName之类的列的表,其中仅使用post.id和post.name更漂亮。

–道格
17年5月12日在0:14

#4 楼

常用或关键列名称(如“名称”或“ Id”)应以TableName开头。

它消除了歧义,易于搜索,意味着当需要两个“ Id”值时,列别名就少得多。

较少使用或审核的列或非关键(例如LastUpdatedDateTime)无关紧要

评论


如果您这样做,我恨您让我额外打字!!!!该表的名称为Person,您认为该ID是什么?汽车?不,是人。

– Jim
2011年10月17日在18:19

@jim,我不认识您,但是输入6个额外的字符大约要花费我半秒钟的时间。考虑到我很少从一个表中进行选择,因此最终会有两个名为“ Id”的列,并且无论如何都需要包含表/别名,因此不会节省键入的字符数。

–CaffGeek
2011年10月17日19:13

@乍得我觉得多余。如果我正在加入,则c.id = m.manufacturerid可以接受。这些列通常以某种方式“映射”到一个类,并拥有一个与Person.PersonId的类,这使我想呕吐...是的,我完全知道我有问题。

– Jim
2011年10月17日19:26

我也不同意这一点。为什么要停止输入名称和ID?为什么每个列都没有前缀表名?选择这两个名称作为前缀似乎是任意的。从概念上讲,您必须具有表才能始终具有列的上下文。为什么不只使用该表名来澄清查询:Person.Name,Animal.Name,Part.Name,...

–托马斯
2011-10-18 17:27

@Bill Leeper,DRY在数据库开发中并不总是适合的。在数据库中,重要的是性能,并使数据库做更多的工作来满足DRY原则(例如使用标量函数或调用视图的查询或返回过多列的查询,或使用游标添加1000000条记录以使用现有proc)通常是禁忌的。不要仅仅因为某些东西在面向对象的世界中是好的就认为它适合数据库设计。您的否决票不合适。使用ID是已知的SQL反模式。

–HLGEM
2011-10-20 21:38

#5 楼

该线程已死,但我想补充一点,IMO不使用Id是一种不好的做法。 Id栏很特殊;它是主键。任何表可以具有任意数量的外键,但只能有一个主键。在所有主键都称为Id的数据库中,一旦您查看表格,就知道确切的列是主键。

相信我,几个月来,我每天都花了整整一天的时间每天在许多大型数据库(Salesforce)中工作,关于模式,我能说的最好的事情是,每个表都有一个名为Id的主键。我可以向您保证,我绝对不会对将主键连接到外键感到困惑,因为PK称为Id。人们没有提到的另一件事是表可以有很长的傻名字,例如Table_ThatDoesGood_stuff__c;这个名字已经够糟糕了,因为架构师早上想起那个桌子时就宿醉了,但是现在您告诉我,不调用主键Table_ThatDoesGood_stuff__cId是不好的做法(记住,SQL列名称通常不区分大小写) 。

老实说,大多数教计算机编程的人所面临的问题是,他们多年来甚至没有编写过任何生产代码,甚至不知道他们是什么工作软件。工程师实际上是这样做的。等到您开始工作,然后再下定决心,认为自己是个好主意。

评论


仅当您的主键都不是复合键时才是这种情况,不幸的是,这种情况经常发生。实际上,应该只在特定情况下使用代理密钥。

–nicodemus13
2012年5月17日下午16:32

像这样使用Id会遇到这样的情况,开发人员不考虑开发人员向他们创建的每个表添加主键ID。关系数据库的基础之一是使用有意义的和聚合的主键,而使用id则无济于事。

– Pieter B
2012年10月20日14:35

这个答案似乎就像您在以自以为是的说法说“我更喜欢Id”。您的观点是,您可以通过找到一个称为Id的键立即查看哪个键是主键。好吧,与tableId完全相同。我可以保证,您永远不会感到困惑,哪个键是主键。我只是寻找在ID之前具有表名称的表。不仅如此,在第一列不是主键的地方您还要使用哪种异类表?我觉得您在此答案中的所有论点纯属优先考虑,类似于“ tableId对我来说是错误的”。

–达林
18-10-13在20:53

@dallin所有的答案都是自以为是的,否则有人会链接到官方标准,而没有一个!

–詹姆斯
19年3月3日在23:44

@James我觉得StackExchange网站的目标是减少有根据的答案。这就是为什么问题过于自以为是而无法解决。诚然,我认为这是为什么这个问题被封闭的原因-因为它引起了有根据的答案,但是我觉得这个特定的答案被过分地考虑了,没有任何真正的支持事实或基于事实的论点。整个答案可以概括为:我认为,您应该使用ID,只是因为这就是我喜欢的。”那不是一个有价值的答案。

–达林
19-6-5'2:28

#6 楼

来自data.stackexchange.com



BOOM,问题已得到解决。
现在告诉老师,SO练习了错误的数据库设计。

评论


我对FK的猜测是基于以下名称:PostTypeId-> PostTypes.Id; AcceptedAnswerId-> Answers.Id; OwnerUserId-> Users.Id。为什么应该将这种简单的做法视为“不好的”做法?

– Sjoerd
2012年4月18日,0:11



这到底如何证明最佳实践?

– GBa
2012年4月18日15:52

是否在堆栈中使用某些东西并不能证明它是好事还是坏事。

– Pieter B
2012年10月20日14:39

事实证明,这种做法绝不妨碍应用程序的可伸缩性和实用性。

–密码
15年2月13日在20:49

实际上,SO实践并不完美。我将使用以下命名:PostType-> PostType.Id; AcceptedAnswer-> Answer.Id; OwnerUser-> User.Id

– alpav
2015年2月17日,2:10

#7 楼

我认为这不是坏习惯。像往常一样,一致性是至上的。

我认为这完全取决于上下文。在表格本身的上下文中,“ id”仅表示您所期望的含义,它是一个标签,可以帮助与其他可能相同(或看起来)相同的其他对象唯一标识。

对于联接,您有责任以使其对您和您的团队可读的方式构造联接。就像用措辞或命名不当可能使事情看起来很困难一样,也可以有效地使用别名甚至注释来构造有意义的查询。

以同样的方式,Java类称为“ Foo”没有以“ Foo”为前缀的属性,不要以表名作为前缀。在上下文中通常很清楚所指的ID是什么。

评论


关系数据库表不是类。

–亚当·罗宾逊(Adam Robinson)
11-10-18在1:23

但是它们是数据结构,它们类似于PODO类。同样的命名问题也适用。

– ocodo
11-10-18在1:28



@Slomojo:不,它们类似于简单的对象。面向对象的设计和数据库的设计是不一样的,甚至是不相关的。尽管在某些情况下它们可以产生相似(甚至相同)的设计,但这并不表示它们是相关的。例如,m:m关系在类中是微不足道的,但是如果没有第三个关联表,则不可能在两个表之间具有m:m关系。

–亚当·罗宾逊(Adam Robinson)
11-10-18在1:55



我不知道这与命名策略有何关系。我的类比(显然吗?)仅局限于此范围。

– ocodo
2011-10-18 2:13



对不起,我的隐含含义不是很清楚,我应该说“从这个意义上讲,它们类似于类”。无论哪种方式,我都不认为对此过于草率特别有建设性。在命名方面,表和类确实有很多相似之处。在死胡同中发展的最佳实践是可以修改的公平游戏,或者至少是可以讨论的。问答中有很多内容可以有效地说明这一点,我没有其他要注意的地方。

– ocodo
2011-10-18 22:36



#8 楼

这使得在表上执行自然连接变得很困难(并且令人困惑),因此,是的,即使不是很糟糕也很糟糕。

Natural Join是SQL Lore的古老工件(即关系代数),您可能已经看到其中之一:perhaps也许在数据库书中。我的意思是,Natrual Join并不是一个新的SQL想法,即使DBMS似乎永远需要花费很多时间,因此对于您来说,实现它不是一个新的想法,您甚至可能无理理会如今它的存在。

好吧,如果您命名所有主键的ID,那么您将失去自然联接的便捷性。 select * from dudes natural join cars将需要写成select * from dudes inner join cars where cars.dudeid = dudes.idselect * from dudes inner join cars where dudes.carid = cars.id。如果您能够进行自然连接,则可以忽略实际的关系,我认为这非常棒。

评论


除非您正在编写存储过程,否则上一次作为应用程序开发人员时,您实际上是编写了全格式的SQL选择器吗?现代语言都包含某种ORM功能,可以为您管理这种关系。列名比能够编写干净的手动SQL重要得多。

– Bill Leeper
11-10-18在15:48

@Bill我每天无休止地做很多很多次,更多地取决于您的代码库,而不是所开发的语言。而且,对于诊断而言,如果您想建立良好的深层关系,则可以将这些自然联接串在一起,并且完全避免查找字段ID。而且,正如圣杰罗姆(St. Jerome)所说:“ SQL的无知就是数据库的无知”。

– Peter Turner
2011年10月18日15:57

除了没有普遍支持自然联接的事实外,IMO还难以理解自然联接。关系中有两列还是只有一列?最好明确一些,避免自然连接。

–托马斯
2011-10-18 17:33

@Thomas,我也不会在代码中加入自然联接,但是对于诊断,我发现在对数据库建模以使其真正起作用时它们非常有用。

– Peter Turner
2011-10-18 17:40

#9 楼

在某些情况下,在每个表上粘贴“ ID”并不是最好的主意:USING关键字(如果支持)。例如,如果您有带有列fooTablefooTableId和带有外键barTablefooTableId列,则可以这样构造您的查询:

SELECT fooTableId, fooField1, barField2 FROM fooTable INNER JOIN barTable USING (fooTableId)


它不仅可以节省键入内容,而且与替代方法相比,它的可读性更高:

SELECT fooTable.Id, fooField1, barField2 FROM fooTable INNER JOIN barTable ON (fooTable.Id = barTable.foTableId)


评论


这是最适合我的答案。 postgres / mysql / sqlite数据库支持USING关键字,这意味着键入更少,而其他答案中的一些列为使用id的原因,最后,在我的主观意见中,可读性更高。

–迈克尔·巴顿(Michael Barton)
16-10-11在17:25

#10 楼

为什么不问你的老师呢?

考虑一下,当所有表PK列都命名为ID时,使用它们作为外键就成了噩梦。

列名在语义上必须有意义。 ID是通用的。

评论


太通用了什么?表的ID?

– Jim
2011-10-17 18:24

@Jim是哪张桌子?单独的id并没有任何意义,尤其是在另一个表的外键的上下文中。这与类无关,而与良好的基本基础关系数据库设计无关。

–user7519
2011-10-17 21:32



稍微有点胖,它属于该表。 table.id是引用ID字段的一种完全可接受的方法。在表名前面加上字段名是多余的。

– ocodo
11-10-18在1:21



@Slomoj,它的输入方式只不过是在列中包括名称,而在将表名别名为Monster Join中的单字母或双字母缩写时,则更为明确。

–user7519
2011年10月18日,下午3:06

您指的是什么噩梦?假设您有一个雇员的自引用结构,其中的一列代表他们的经理。您怎么称呼外键?您不能将其称为EmployeeId,因为它大概是您的PK。 FK的名称不必与PK匹配。应该为它所包含的实体所代表的名称命名。

–托马斯
2011-10-18 17:30

#11 楼

ID不好是由于以下原因:

如果要执行许多报告查询,则要同时查看这两个列,必须始终对列进行别名。因此,当您可以正确命名时,就浪费了时间。这些复杂的查询已经足够困难(我编写的查询可能长达数百行),而没有增加不必要的工作负担。

它会导致代码错误。如果您使用允许使用自然联接的数据库(不是我认为您应该使用自然联接,但是当功能可用时,有人会使用它们),如果您得到使用它的开发人员,那么您将加入错误的事物。

如果要复制联接以创建复杂的查询,则很容易忘记将别名更改为所需的别名并获得不正确的联接。如果每个ID均以其所在的表命名,则通常会出现语法错误。如果pPK名称和FK名称匹配,则更容易发现复杂查询中的联接是否不正确。

评论


+1:这些是我认为令人信服的原因,而其他反对ID的答案根本无法说服我。

–phoog
2012年4月19日在20:31

回复:“如果您要复制联接以创建复杂的查询”,那么您的问题就是复制和粘贴。停止复制和粘贴,您将看到car.id命名有多么方便。对于FK连接,请使用car.mfg = mfg.id,car.color = color.id,car.model = model.id-非常简单,并且与您在LINQ中编写的内容相匹配。

– alpav
2015年2月17日在2:06

尝试用30个连接写东西,您会明白为什么它是反模式。

–HLGEM
15年2月18日在14:19

混淆是首要的原因-在编写大型复杂报告时实在令人头疼。自然加入只是一个甜蜜的收获。令人惊讶的是,其他答案只是忽略了这一点。我认为,添加一些示例可以使问题更清楚,并将答案提高到应有的水平。

–卢卢
18年7月29日在19:01



#12 楼

有一些答案可以解决我认为不使用“ id”作为表中主键的列名的最重要原因:一致性和减少的歧义。

但是,对我来说,主要的好处是维护程序员(尤其是那些不参与原始开发的程序员)实现的。如果您在Person表中的ID中使用名称“ PersonID”并始终使用该名称作为外键,那么对模式编写查询以找出哪些表具有PersonID而不用推断“ PersonID”就很简单了。是外键时使用的名称。请记住,对与错,并非总是在所有项目中都强制使用外键关系。

在一个极端的情况下,一个表可能需要在同一张表上有两个外键,但是在这种情况下,会将原始键名作为该列的后缀名,因此通配符%PersonID也可以轻松找到这些实例。

是的,可以通过具有“ id”并知道始终将其用作“ tableNameID”的标准来完成许多工作,但这需要既知道实践已到位又取决于原始开发人员将遵循不太直观的标准做法。

虽然有人指出要写出更长的列名确实需要一些额外的按键操作,但是我认为编写代码只是程序活动寿命的一小部分。如果要节省开发人员的击键作为目标,则永远都不要写注释。

作为一个已经花了很多年维护大型项目并包含数百个表的人,我强烈希望表中键的名称保持一致。

评论


假设“公司”表具有2个“人”表的外键。一个代表公司总裁;另一个代表公司总裁。另一个代表公司的财务主管。您真的可以称呼PersonID1和PersonID2列吗?将它们称为PresidentID和TreasurerID更具描述性。我发现阅读内部联接Person AS Presidents ON Company.PresidentID = Presidents.ID比内部联接Person AS Person1 ON Company.PersonID1 = Person1.PersonID容易得多

–phoog
2012年4月19日在20:28

否。在您的示例中,我可能会有一个CompanyOfficer或CompanyPerson表,该表允许Company和Person之间建立多对多关系,并提供有关关系性质的其他信息。如果要在Company表中实现它,我将使用列名PresidentPersonID和TreasurerPersonID保留名称的* PersonID部分,同时添加其他描述符。内部加入Person作为Company.PresidentPersonID上的Presidents.Presidents.PersonID

–玛拉基
2012年4月25日在16:28

#13 楼

使用ID作为主键字段的实践导致将ID添加到每个表的实践。许多表已经具有唯一标识记录的唯一信息。使用THAT作为主键,而不是添加到每个表的id字段。这就是关系数据库的基础之一。

,这就是为什么使用id是不好的做法:id通常不只是信息的自动增加。

请考虑以下表格:

PK id | Countryid   | Countryname
    1 |         840 | United States
    2 |         528 | the Netherlands


该表的问题是,它使用户可以添加另一行:美国,使用国家代码840。这只是破坏了关系的完整性。
可以在各个列上强制唯一性,或者您可以只使用已经可用的主键:

PK Countryid   | Countryname
           840 | United States
           528 | the Netherlands


这样,您可以使用已经拥有的信息作为主键,是关系数据库设计的核心。

评论


您将了解为什么当人们不得不在不同系统之间迁移数据库,或有将数据库合并在一起的乐趣时,人们会向每个表添加一个通用键列的原因。

–密码
15年2月13日在20:56

有时候是这种情况,但是以我的经验,拥有一个不错的唯一不变键是很不常见的。但是即使在您的示例中,您也可以使用无意义的唯一编号来标识国家/地区,只是由ISO而非数据库分配的一个。

– CodesInChaos
2015年6月22日14:33



现在,当国家名称更改时,您必须在整个数据库中对其进行更新以进行修复。如果您只是使用代理密钥(如...“ id”),则更新将是微不足道的。自然键很棒-当它们完全不可变且永不改变时。实际上,很少有这种情况是正确的。

– Gerrat
18 Mar 6 '18 at 20:31

@Gerrat:如果国家/地区名称更改,则ISO 3166-1数字代码保持不变,只有ISO 3166-1 alpha-2和alpha-3代码更改。例如,这发生在缅甸。同样,如果一个国家更改了地域但保留了名称,ISO 3166-1数字代码也会更改,但是ISO 3166-1 alpha-2和alpha-3代码会保留。这是在南苏丹从苏丹分裂而厄立特里亚从埃塞俄比亚分裂时发生的。东德和西德重新统一后,他们保留了西德的alpha-2和alpha-3代码,但获得了新的数字代码。当国家完全解散或转型时(请考虑……

–Jörg W Mittag
19年6月9日在15:18

……是90年代巴尔干战争的产物),它们同时获得了新的数字代码以及alpha-2和alpha-3代码。

–Jörg W Mittag
19年6月9日在15:19

#14 楼

我总是将“ id”用作每个表的主列名称,只是因为它是我使用的框架(Ruby on Rails,CakePHP)的约定,所以我不必一直覆盖它。

这不会打败我的学术原因。

#15 楼

如果使用正确,我认为这不是一个坏习惯。通常有一个永远不需要接触的自动递增的ID字段,称为“ ID”,并为应用程序使用一个友好的标识符。编写类似from tableA a inner join tableB b on a.id = b.a_id的代码可能有点麻烦,但是可以将这些代码隐藏起来。

作为个人喜好,我倾向于在ID前面加上实体名称,但我看不到如果完全由数据库处理,仅使用Id就是一个真正的问题。

评论


您永远都不会通过eaches主键来连接两个表,尤其是自动递增的id。上面的示例来自a.id = b.table_a_id上的tableA的内部联接tableB b。

– Bill Leeper
11-10-18在15:51

是的,这就是我的意思。几乎是午餐时间,需要精力。

–韦恩·莫利纳(Wayne Molina)
2011-10-18 15:54

#16 楼

ID已经足够普遍了,我认为它不会使任何人感到困惑。您总是想知道这张桌子。将字段名称放在生产代码中而不包含表/别名是一种不好的做法。如果您过于担心能否快速键入即席查询,那么您就自己一个人。

只希望没有人开发一个ID保留字的sql数据库。

CREATE TABLE CAR (ID);


在一个漂亮的2个字符的小程序包中,以1开头的字段名称,主键和自动增量为1。哦,我会叫它CARS,但是如果我们要节省按键操作,谁真的认为一个叫CAR的表将只有一个?

评论


这说明了为什么形式关系理论的知识很重要,表名表示单行是什么。表格Car代表一个表格,其中每行代表一个Car。调用汽车改变了语义,并显示出对形式关系理论基本原理的完全缺乏理解。 Rails是一个足够了解危险的人的典型例子。

–user7519
2015年5月6日19:44

#17 楼

这个问题一遍又一遍,但我想我也要加我的见解。


我使用id表示那是每个表的标识符,所以当我联接到表,我需要主键我自动联接到主键。
id字段是一个自动递增的,无符号的(意味着我永远不必设置其值并且它不能为负)
对于外键,我使用tablenameid(同样是样式问题),但是我加入的主键是表的id字段,因此一致性意味着我可以随时轻松地查询查询
id又短又甜
其他约定-所有表和列名均使用小写字母,因此不会因大小写而出现问题


#18 楼

要考虑的另一件事是,如果主键名称与外键名称不同,则无法使用某些第三方工具。例如,您将无法加载架构放入Visio之类的工具中并生成准确的ERD。

评论


但这可能是第三方工具的错。列命名约定不能替代工具应自检的实际外键。

– Gerrat
19年6月11日19:49

#19 楼

我发现这里的人们几乎涵盖了各个方面,但是我想补充一点,“ id”不是,也不应该被理解为“标识符”,它更像是“索引”,并且肯定不会声明或描述行的身份。 (我在这里可能使用了错误的措辞,请改正我的意思)。

人们阅读表数据和编写代码的方式或多或少。我个人认为,这很可能是我最常看到的最流行的方式,是编码人员将完整的引用写为table.id,即使他们不需要进行联合或/和联接也是如此。例如:

SELECT cars.color, cars.model FROM cars WHERE cars.id = <some_var>


这样,您可以将其翻译为英语“给我编号为的那辆汽车的颜色和型号。”而不是“给我识别为数字的那辆汽车的颜色和型号”。该ID不会以任何方式代表汽车,它只是汽车的索引,如果可以的话,它是序列号。就像当您要从数组中获取第三个元素时一样。

因此总结一下,我想补充的是,这只是一个偏好问题,所描述的读取SQL的方式最受欢迎。

尽管如此,在某些情况下没有使用它,例如(一个非常少见的例子),当ID是真正描述的字符串时。例如id = "RedFordMustang1970"或类似的东西。我真的希望我至少可以解释一下以了解这个想法。