为什么前缀列名称被认为是不好的做法?


25

根据一个流行的SO帖子,给表名加上前缀被认为是不好的做法。在我公司,每列均以表名作为前缀。这对我来说很难读。我不确定原因,但这实际上是公司的标准。我不能忍受命名约定,但是我没有文档来支持我的推理。

我所知道的是,阅读AdventureWorks非常简单。在这个我们公司的数据库中,您将看到一个表Person,它可能具有列名:

Person_First_Name
甚至
Person_Person_First_Name(不要问我为什么看到2x人)

为什么前缀列名被认为是不好的做法?下划线在SQL中也被认为是邪恶的吗?


注意:我拥有Pro SQL Server 2008-关系数据库的设计和实现。欢迎引用该书。


2
看起来制定这些规则的人似乎不了解别名功能。
ba__friend 2011年

@Daniel Pryden-我用了不好的措词。问题已更新。
P.Brian.Mackey 2011年


@ba__friend-您能详细说明一下我吗?
P.Brian.Mackey 2011年

1
您使用的基本单词是标准。如果您更改标准做法,则会出现不一致之处。老实说,您是否认为对这种标准做法的任何更改是否值得引起不一致?现状真的比这差吗?

Answers:


44

下划线不是邪恶的,只是很难键入。不好的是在不固定所有现有对象的情况下在中间更改标准。现在您有了personId,Person_id等,并且不记得哪个表使用了下划线。命名的一致性(即使您个人不喜欢名称)也有助于简化编码。

我个人认为唯一需要在列中使用表名的地方是在ID列中(仅ID的使用是数据库设计中的反模式,因为进行过大量报表查询的任何人都可以告诉您。重命名非常有趣每次编写报告时,查询中的12列。)这也使得更容易立即知道其他表中的FK,因为它们具有相同的名称。

但是,在成熟的数据库中,要做的工作比更改现有标准还值得。只需接受这是标准并继续前进,还有许多重要的事情需要首先解决。


4
是的,但是没有一致的命名标准的数据库比一致应用的标准较差的数据库难得多。
HLGEM 2011年

2
我部分同意。如果数据库很大,则保留标准。但是我花更多的时间阅读代码而不是编写代码,而表名前缀似乎更容易筛选。如果是我,并且知道我可以在几天或一周内对其进行重构,那么我肯定会的。但是很多时候您没有那么奢侈,必须保留编码产品,产品,产品的代码。
程序员

3
@jason,您可能会打破自己的想象。应用程序程序员通常不知道许多事情,而数据库却经常被访问。诸如从客户端或其他数据库导入数据,然后导出到客户端和/或数据仓库,其他应用程序,报告等之类的事情。您可以在几小时内习惯于阅读任何标准,并且无需同意就可以重构出已批准的公司标准。改用新标准会让您被炒鱿鱼。老实说,除非数据库尚处于起步阶段,否则无论您是否喜欢它,都最好使用现有标准。
HLGEM 2012年

7
@jason,我是数据库人,众所周知,我们没有冒险意识!
HLGEM

2
完全同意TableName.Id是反模式。在这种模式下工作了足够长的时间,并且我有足够的信心可以说TableName.Id发生的错误/混乱与TableName.TableNameId不会发生
AaronLS 2013年

16

联接多个表时以及查询创建者不使用别名时,列名前缀的参数将防止名称“冲突”。

SELECT person.name, company.name FROM person JOIN company ON ...

SELECT * FROM person JOIN company ON ...

这两个查询都将具有两个“名称”列(name_1,name_2),而不会“告诉”它属于哪个实体。而且您永远无法确定所生成的列名称(将是name_2或name_3还是...)。如果使用表名前缀,则列名将为person_namecompany_name,因此您知道其所属的每个名称,此外您还知道列名将保持不变(例如,如果使用JDBC在Java中获取它们,例如)。

如果使用别名,则可以忽略这两个参数,但是我认为,公司强制执行的大多数编码约定都是许多(初级)程序员未遵循良好做法的结果。例如,在这种情况下,在SELECT语句上使用通配符可能会导致没有名称前缀的问题。

至于表名和列名中的下划线,由于我只使用小写的名称加上下划线作为分隔符,因此我广泛使用它。仅使用小写字母有助于将标识符与SQL关键字(我用大写字母键入)区分开来:

SELECT person_name, COUNT(bought_product) FROM bought_products WHERE person_name LIKE 'A%'

6
如果在不同表中具有相同信息的所有列都具有完全相同的名称,并且每当您使用多于1个表别名将成为强制执行的标准,我将非常喜欢。厌倦了记住patid,Patientid,pat_id,id_pat或ptatient_id映射到哪个表。
Pieter B

1
我绝不会在不别名所有列的情况下编写生产查询。它使维护变得非常容易。当然,我编写了复杂的报告/导出类型查询,最多包含10-20个连接和30-50个列,六个月后,很难记住该列来自哪个表。
HLGEM 2015年

8

将这些前缀添加到列名将使表更难以扩展。举个例子:如果最终您意识到想要/需要更改表名,则将不得不修改整个表结构(即,不仅是表名,而且是表中所有列的名称)。这也将使更新表的索引和查询它的客户端代码更加困难。


4

还有,如果(你的链接上按帕特里克·凯驰的答案),明智地使用,这将是不明确的例外公共列名(通常只ID,有时名称)过于频繁

另一个最佳做法是始终限定查询中的列和对象。因此,列前缀变得毫无意义,并使您的代码混乱。

比较一下:哪个是最简单的眼睛?

SELECT P.name, P.Salary FROM dbo.Person P

SELECT Person.Name, Person.Salary FROM dbo.Person Person

SELECT dbo.Person.name, dbo.Person.Salary FROM dbo.Person

SELECT Person.Person_name, Person.Person_Salary FROM dbo.Person Person

3
绝对是第一个……:)
ErikE 2011年

3
SELECT name, salary FROM dbo.Person呢 :P
cHao 2011年

1
@cHao:尝试创建与上SCHEMABINDING视图...
GBN

@gbn:对我来说很好。 CREATE VIEW [dbo].[vwMeritPercentage] with schemabinding AS SELECT [Performance Score] as dblMinScore, ISNULL(( SELECT TOP 1 [Performance Score] FROM dbo.Budget b WHERE b.[Performance Score] > budget.[Performance Score] ORDER BY [Performance Score] ), 100.00) as dblMaxScore, [Merit Minimum] as dblMinPercentage, [Merit Midpoint] as dblBudgetPercentage, [Merit Maximum] as dblMaxPercentage FROM dbo.Budget;
2011年

1
相关文档(msdn.microsoft.com/zh-cn/library/ms187956(v=SQL.105).aspx):“使用SCHEMABINDING时,select_statement必须包含表的两部分名称(schema.object),视图或引用的用户定义函数。” 请注意,不需要点名(除非需要使用点名来解决查询中的歧义),而仅是表,视图和函数。
2011年

3

总的来说,似乎并没有普遍存在的标准。您链接到的问题具有几个约定完全不同的高投票答案。当然,每个人都将捍卫自己的标准,并且在项目中保持一致的约定更为重要。

就是说,为列名加上前缀似乎是过大的。您已经知道要使用哪个表,并且可以使用表或列别名轻松解决来自不同表的两个列具有相同名称的情况。


2

在TSQL中,如果要避免歧义,可以以TableName.FieldName的形式引用字段,因此,将表名添加到字段名实际上会降低可读性,使其成为TableName.TableName_FieldName或类似名称。我认为是否使用下划线更多是个人选择。我更喜欢CamelCase,当我想添加一个后缀或类似的名称(例如TableName_Temp)时,我使用_,但这仅是我自己。


2

我曾经在一个系统上工作,在该系统上,我们决定使用短代码为列添加前缀。PK字段使用“完整表名”作为前缀,所有其他列始终使用2-4个字符作为前缀。每列还使用数据域作为后缀。如果始终如一,它可能会非常干净。一类或另一类的命名标准牵扯到草率的编码,这是胡说八道。保持一致的标准很重要。我已经看到许多数据库不一致,因为没有明确的标准,而且比其他任何事情都向我表明,数据结构可能有麻烦。如果数据库的设计人员甚至无法一致地命名对象及其子对象,


1

前缀是不好的做法,因为前缀会导致其设计要防止的问题。如您所述,很难读取带前缀的列。如果在连接两个表的查询中最后出现重复的列名,则可以解决它们的问题,或者是视图,存储过程或表格用户定义的函数,如果您发现自己不断地连接特定的表​​,则可以为您解决。

至于在表名中使用下划线,这是一个宗教论点。最后,如果能提高知名度并使事情变得更容易,那就去做吧。我通常不会在列或表名中包含空格或表。但是,对于仅由报告包使用或导出到CSV文件的表或视图,我可能会例外。


1

许多数据库对列名(例如Oracle)中的字符数有严格的限制。

如果使用允许长列名的数据库,但后来又决定要将该结构迁移到另一个数据库系统,则前缀将增加列名无效的机会。

尽管您现在正在使用SQL Server,但是没有人可以预测未来,并且您的软件将来可能必须在多个数据库上运行。


0

考虑编写数据字典(或“注册表”)。我的意思是指包含模型中所有数据元素的文件:名称,描述等。它应独立于模型的实现,例如,不应提及表名。您如何消除“ ID”,“ Type”和“ Code”等名称的歧义?

一种方法是遵循国际标准ISO / IEC 11179的准则-毕竟,为什么要重新发明轮子?基本结构是:

[Object] [Qualifier] Property RepresentationTerm

在元素之间使用分隔符:列名中的空格不能很好地与SQL配合使用,并且下划线在视觉上效果很好。

我有一种感觉,您组织中的某个人在提出诸如的元素名称时会尝试遵循这些准则Person_Person_First_Name

我想展示的示例是UK Nation Health Service(NHS)数据字典

因此,我认为您不必使用的命名约定听起来太糟糕了。

在实现时(例如在SQL中),有些人喜欢在表名提供上下文时省略Object,Qualifier和Property子元素,例如在表中person_first_name变为等。但是,经验法则是,数据元素不应简单地更改其名称由于它在物理模型中的位置似乎是一个不错的选择。如果认为遵循此规则不是一个好主意,则应该承担记录所有他们使用过的名称变体的任务:)first_namePerson

您可以在Joe Celko的《编程风格》一书中找到ISO 11179的一个不错的摘要,其中包括在列名中首选使用下划线作为分隔符的证据。


0

一些人发现在代码中更容易知道数据来自哪个表,但是,如果您正在谈论的是面向对象的系统,则应使用名称的上下文来知道数据来自何处,在这种情况下为表名。

就个人而言,表名前缀表明开发人员不是很熟练,随着您的深入研究,您会发现许多其他不良的编码约定,并且如果我不得不猜测应用程序中有太多表,有问题,等等。

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.