为什么将表的主键列“ Id”命名为不良做法?[关闭]


209

我的T-SQL老师告诉我们,在没有任何进一步说明的情况下,将PK列“ Id”命名为不良做法。

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


27
好吧,它实际上不是描述,Id表示“身份”,这很容易解释。那是我的意见。
Jean-Philippe Leclerc

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

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

57
您有一个表格...它叫People,其中有一个列,称为Id,您认为Id是什么?一辆车?一条船?...不,是人民ID,仅此而已。我认为这不是一个坏习惯,除了Id之外,也不必为PK列命名。
吉姆,

38
所以老师走上了全班,告诉你这是一个不好的练习,没有任何原因?对于老师来说,这是更糟糕的做法。
JeffO

Answers:


247

我要说出来:这并不是一个不好的做法(即使是这样,也不是那么糟糕)。

您可以使参数(如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”的问题更像是一种品味问题,而不是一种不好的做法。


编者注:此查询中的错误是有意的,并被用来说明问题。编辑之前,请先阅读完整答案。


1
@Chad,是在以下情况下的引用:在该特定查询中,即使没有任何意义,您也使用3个字母作为表名的别名(cars-> car。感谢上帝,您省了我的手指)。不要读得太深。
riwalk

3
比我的别名更糟糕的是,我将复数cars和混合使用manufacturer。一个是复数,另一个不是。如果人们想选择数据库,那是应该选择的错误做法。
CaffGeek

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

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

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

123

因为当您有一个带有外键的表时,您不能将该外键命名为“ 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列,以便区分它们。

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

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


174
不确定这对我来说是否足够好。说没有错SELECT * FROM cars c JOIN manufacturer m ON manufacturer.Id = c.ManufacturerId。我已经使用id了多年,但从未发现您所描述的是一个真正的问题。
riwalk

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

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

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

6
@gbn,再次说明,只要您简单地消除所有歧义即可SELECT manufacturer.id FROM ...。由此产生的每一个困难id都可以很容易地克服,这仅仅是一个品味问题。
riwalk

66

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


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

12
ID是更为繁琐的阅读
HLGEM

5
@HLGEM:总是可以用表名来限定列名。
凯文·克莱恩

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

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

40

通用或关键列名称(如“名称”或“ Id”)应以TableName为前缀。

它消除了歧义,易于搜索,并且在需要两个“ Id”值时意味着更少的列别名。

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


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

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

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

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

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

31

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

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

老实说,大多数教计算机编程的人的问题是,即使有多年,他们也没有写过一条生产代码,而且他们不知道软件工程师实际上会做什么。等到您开始工作,然后再下定决心,认为是否是一个好主意。


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

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

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

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

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

24

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

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

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

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


5
关系数据库表不是类
亚当·罗宾逊

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

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

1
我不知道这与命名策略有何关系。我的类比(显然吗?)仅在此范围内。
ocodo 2011年

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

24

来自data.stackexchange.com

帖子中的ID

BOOM,问题已回答。
现在去告诉您的老师,SO练习不良的数据库设计。


8
我的猜测在FKS的基础上,名称:PostTypeId -> PostTypes.Id; AcceptedAnswerId -> Answers.Id; OwnerUserId -> Users.Id。为什么应该将这种简单的做法视为“不好的”做法?
Sjoerd 2012年

3
这到底如何证明最佳实践?
GBa 2012年

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

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

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

17

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

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

好吧,如果您命名所有主键的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

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

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

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

16

在某些情况下,在每个表上粘贴“ ID”并不是最好的主意:USING如果支持,则使用关键字。我们经常在MySQL中使用它。

例如,如果您具有fooTablewith列fooTableIdbarTable外键fooTableId,那么您的查询可以这样构造:

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)

这是最适合我的答案。该USING关键字受postgres / mysql / sqlite数据库支持,这意味着键入较少,而其他答案中的某些列为使用的原因id,最后在我的主观意见中更易读。
迈克尔·巴顿

11

为什么不问老师呢?

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

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


8
太通用了什么?表的ID?
吉姆

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

10
要稍微胖一些,它属于该表。table.id是引用id字段的一种完全可以接受的方式。在表名前面加上字段名是多余的。
ocodo 2011年

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

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

7

ID错误是由于以下原因:

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

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

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


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

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

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

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

5

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

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

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

是的,这可以通过具有“ id”并知道始终将其用作“ tableNameID”的标准来完成,但是这既需要知道实践已经到位,又要取决于原始开发者来减少使用“ id”直观的标准做法。

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

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


假设一个Companies表有2个外键Persons。一个代表公司总裁;另一个代表公司总裁。另一个代表公司的财务主管。你真的叫列PersonID1PersonID2?称它们为PresidentID和将更具描述性TreasurerID。我觉得更容易阅读inner join Person AS Presidents ON Company.PresidentID = Presidents.IDinner join Person AS Person1 ON Company.PersonID1 = Person1.PersonID
phoog

1
否。在您的示例中,我可能会拥有一个CompanyOfficerCompanyPerson表,该表允许在关系之间Company以及Person关系性质的其他信息之间建立多对多关系。如果要在Company表中实现它,我将使用列名PresidentPersonIDTreasurerPersonID在添加其他描述符时保留名称的* PersonID部分。 inner join Person as Presidents on Company.PresidentPersonID = Presidents.PersonID
玛拉基2012年

5

使用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

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


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

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

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

@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代码,但获得了新的数字代码。当国家完全溶解或变换(觉得...
约尔格W¯¯米塔格

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

4

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

这不会超出我的学术原因。


2

如果使用正确,我认为这不是一个坏习惯。通常有一个永远不需要接触的自动递增的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

是的,这就是我的意思。几乎是午餐时间,需要精力。
韦恩·莫利纳

2

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

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

CREATE TABLE CAR (ID);

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


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

2

这个问题一遍又一遍地被质疑,但我认为我也将补充我的意见。

  1. 我用id表示那是每个表的标识符,所以当我加入一个表并且需要主键时,我会自动加入该主键。

  2. id字段是一个无符号的自动递增(这意味着我永远不必设置其值,并且它不能为负)

  3. 对于外键,我使用tablenameid(同样是样式问题),但是我加入的主键是表的id字段,因此一致性意味着我可以随时轻松地查询查询

  4. id也很简短

  5. 其他约定-所有表名和列名均使用小写,因此不会因大小写而出现问题


1

要考虑的另一件事是,如果主键名称与外键名称不同,则无法使用某些第三方工具。

例如,您将无法将架构加载到Visio之类的工具中,而无法生成准确的ERD。


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

1

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

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

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

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.