将“tbl”前缀添加到表名真的是个问题吗?

Rac*_*SQL 101 sql-server best-practices naming-convention

我正在观看一些 Brent Ozar 视频(例如这个视频),他建议不要在表格前加上‘tbl’‘TBL’

在网上我发现一些博客说它没有增加文档,而且“阅读它需要更长的时间”。

问题和考虑

  • 这真的有问题吗?因为自从我的第一份 dba 工作(高级 DBA 告诉我为组织这样做)以来,我就在表前加上了 'tbl' 前缀。
  • 这是我需要摆脱的东西吗?我做了一些测试,复制了一个非常大的表并给它加上了 'tbl' 前缀,同时保持另一个没有它,我没有注意到任何性能问题。

bil*_*nkc 221

我曾经有一张桌子,它闪亮而美丽。它持有一个组织的所有财务交易。然后我们开始将数据加载到其中。

在当月,他们可以根据需要随时声明和重述值。在一个月的最后 10 天,他们会重述数字 -> 运行 ETL 处理 -> 每天多次查看报告。月份结束后,书籍将被密封,并且无法修改值。

一家金融服务公司生成的财务数据之多令人惊讶……我们在测试数据集时没有意识到数据量会使他们的月末流程站不住脚。在用新的试运行替换它之前删除“当月的数据”花费了越来越长的时间。

我们必须做一些事情来加快处理速度,同时又不破坏“谁知道什么”的未编入目录,这完全取决于 MonthlyAllocation 表。我决定扮演魔术师,把桌布从他们下面抽出来。我去老派并使用了Partitioned View。数据已经有一个 IsComplete 标志,所以我做了两个表——每个表都有相反的检查约束:MonthlyAllocationComplete、MonthlyAllocationInComplete

然后我创建了与原始表同名的分区视图:MonthlyAllocation。对于我们对数据库所做的物理更改,没有哪个过程更明智。没有报告中断,直接访问的分析师都没有报告该“表格”之前或之后的任何问题。

很酷的故事兄弟,但你要去哪里?

如果他们有一个命名约定,tbl_MonthlyAllocation 呢?怎么办?我们是否花费大量工时浏览组织中的每个 ETL、每个报告、每个临时电子表格并更新它们以使用 vw_MonthlyAllocation?当然,所有这些变更都会通过变更委员会,这始终是一个快速而轻松的过程。

你的老板可能会问:公司再次工作的回报是什么?

另一种选择是我们将此视图命名为 tbl_,而不是花费所有时间来测试、更新和部署代码。这变成了一个有趣的轶事,你向所有新员工和注意力不集中的人解释了为什么你与对象的命名不一致

或者您不使用冗余元数据对对象进行双重编码。数据库会很高兴地告诉你什么是表,什么是视图,什么是表值函数等等。

命名约定很好,只是不要把自己画在一个角落里。


Bre*_*zar 143

布伦特在这里(你在问题中指的那个人)。

我告诉你不要在你的表名前面添加 tbl 的原因与我说不要在你孩子的名字前面添加 child 的原因相同。你不叫他们孩子约翰和孩子简。它不仅不会增加任何价值,而且在以后的生活中它们可能不再是一个孩子——而且你的对象以后可能会变成视图。


Aar*_*and 118

这是一个非常主观的论点,但这是我的看法:tbl 前缀没有用。

您在查看代码的情况下有多少种情况,但无法分辨是表格还是其他内容?

除了在对象资源管理器中查看表列表时,tbl 增加了什么价值,您必须做更多的工作才能找到要查找的表?

有些人说他们希望在处理表或视图时在他们的代码中清楚这一点。为什么?如果这很重要,为什么不只以特殊方式命名视图?在大多数情况下,它们就像桌子一样,所以我认为区分的价值不大。

  • 例如,在 PostgreSQL 中,视图实际上也是一个表:https://www.postgresql.org/docs/9.6/static/rules-views.html - 所以区别就更不重要了。 (11认同)

Phi*_*lᵀᴹ 42

这是一种可怕的做法。

tbl
tbl_
Table_
t_
Run Code Online (Sandbox Code Playgroud)

...在生产中看到它们。

我目前正在使用的产品之一有一半名为 的表tbl_whatever,另一半名为“正常” - 他们显然有按照不同标准工作的开发人员。他们的另一个坏习惯是在作为外键的列名前加上fk,然后是表名,fk然后是列名,给出像fktbl_AlarmsfkAlarmsID. 该命名约定只是整个tbl_%口头禅的逻辑延伸,您可以看到它变得多么荒谬!

我几乎忘记了另一个让我每天哭泣的数据库。数据类型前缀列名... dtPaymentDate,因为名称真的需要dt前缀?`

  • 至少你没有使用区分大小写的数据库,所以 tbl_Foo 和 Tbl_Foo 不是不同的实体...... (23认同)

Eri*_*ikE 27

comDon't verListen prepTo adjThose adjOther nouPeople. proYou auxShould advAlways verUse nouPrefixes prepWith proYour adjTable nouNames。proI auxHave 已经开始使用 proThem prepIn adjNormal nouWriting。

com参见 advHow adjEffective proIt verIs?nouPeople auxCan verUnderstand proYour nouWriting adjBetter!


小智 21

使用这样的前缀称为匈牙利符号。它的前提很简单:你可以通过它的命名方式来确定它是什么。这在编程语言中尤其常见,尤其是当开发人员由于缺乏技能或缺乏语言功能而编写跨越数十页的单体函数时。它是帮助开发人员保持数据类型清晰的助记符。

一般来说,这种命名风格很可能用在非常旧的代码中,或者被刚刚学习(并且碰巧学会了这种习惯)的开发人员使用,或者只要他们记得就一直在这样做。根据我的经验,我观察到,如果没有通过编程课程或教程介绍匈牙利符号,那么很少有经验不足的开发人员会自发地使用匈牙利符号。他们更有可能使用变量名,如ixacct

除了把自己画成一个角落,这真的只是填充物。SQL 语法足够精确,开发人员应该始终知道他们是在谈论字段、记录还是数据集(可能是表、视图等)。虽然它可能是一个很好的教学辅助工具,但这种语法通常不应该存在于生产数据库中。它可能会损害易读性,并使找到您要查找的表格变得更加困难,尤其是在弹出多个替代命名主题时,例如tbltabletab等。

数据库并不真正关心什么,你打电话给你的表,字段等,他们只是字节由它们的人类操作员或脚本安排在一个特定的顺序数据。但是,必须维护这些数据的人会喜欢有意义的名称,例如“用户”、“订单”和“帐户”。如果您使用 SQL 查询,这也更实用,例如“show table like 'a%'”。使用前缀和后缀可能会不必要地使原本微不足道的维护复杂化。

  • 像许多滥用匈牙利符号的人一样,您反对它的答案完全忽略了 Apps Hungarian 和 Systems Hungarian 之间的区别。 (14认同)
  • @BenVoigt,非常真实。但是您忘记了 [强制链接](http://www.joelonsoftware.com/articles/Wrong.html)。 (8认同)

Nel*_*son 12

在我继承了我的第一个 SQL Server 实例之后,我已经阅读了一些像这样这样的博客文章(有很多),并注意到许多对象带有前缀,我想开始使用更简洁的方法和单一命名约定开发新的对象(对我来说[和可能的其他开发人员]在对象关系映射上工作要容易得多)。

其中最广泛使用的前缀是Tbltbl,但后来我不得不TBLtbl_*TableName*_Tbl

在此处输入图片说明

在尝试从 Visual Studio 查询和工作时,这简直是地狱,我对一整套表的前缀并不重要,tbl但请至少对整个数据库保持这种方式。

所以最后我肯定会说这是个人喜好的问题,但这也与一致性有很大关系,如果你沿着这条路走下去,很多人会很高兴,至少你在发展过程中保持不变。

...另一方面我只想说,如果你采取其他方法,去使用无前缀的单数表,你将来会让开发人员高兴,还有什么比高兴更重要?


sam*_*ris 11

是的,添加一个表示对象类型的前缀是一个问题,而且是不必要的。因为,

  1. 有时对象以某种东西开始生命,但最终变成别的东西。(例如,由于某种原因,表tblXxx被拆分为tblXxxYtblXxxZ并替换为连接两个新表的视图。现在您有一个名为 的视图tblXxx)。
  2. 当您tbl在编辑器中键入时,其自动完成功能会挂起 45 秒,然后显示 4000 个条目的列表。

但...

我将扮演魔鬼的拥护者,并说出其他人完全反对的话。在极少数情况下,后缀/前缀可能有用,这是我工作的组织的一个示例。

我们有一个基于实体的 ERP 系统,其中的业务逻辑是用 Oracle PL/SQL 编写的。它已经有将近 20 年的历史了,但却是一个非常稳定的系统(这不是一个遗留系统。我们正在不断地开发它)。

该系统是基于实体的,每个实体关联一个表、多个视图、多个 PL/SQL 包和许多其他数据库对象。

现在,我们希望属于同一实体的对象具有相同的名称,但仍可区分其用途和类型。因此,如果我们有两个名为CustomerOrderand 的实体CustomerInvoice,我们将拥有以下对象:

  1. 存储数据的表[TAB后缀]:
    • CUSTOMER_ORDER_TAB
    • CUSTOMER_INVOICE_TAB.
  2. 客户端使用的视图[无后缀]:
    • CUSTOMER_ORDER
    • CUSTOMER_INVOICE.
  3. 基本操作界面;(PL/SQL 包)[API后缀]:
    • CUSTOMER_ORDER_API
    • CUSTOMER_INVOICE_API.
  4. 报告生成器;(PL/SQL 包)[RPI后缀]:
    • CUSTOMER_ORDER_RPI
    • CUSTOMER_INVOICE_RPI.
  5. 主键索引 [PK后缀]:
    • CUSTOMER_ORDER_PK
    • CUSTOMER_INVOICE_PK.
  6. 二级索引[IX后缀]:
    • CUSTOMER_ORDER_XXX_IX
    • CUSTOMER_INVOICE_XXX_IX(其中XXX描述了索引的用法)。
  7. ... 等等。

这确实是Apps Hungarian 的一种形式(请注意,相同类型的对象可以根据用途具有不同的后缀)。但是,使用后缀而不是前缀。我不能告诉你这个系统如何如此容易阅读。IntelliSense 实际上有效,因为TBL我可以输入Customer并获取属于名为Customer*.

所以,在这里我已经展示了如何元数据可以是有用的。目的是让一组相关的数据库对象可以通过单个名称识别,但根据它们的用途来区分它们

话虽如此,如果您没有这种系统,则没有使用前缀或后缀object的类型

请注意,我们没有使用后缀,如_table, _package, or _view(即对象的类型)。例如,(3) 和 (4) 都是 PL/SQL 包,但使用不同的后缀。(5) 和 (6) 也是一样,都是索引。所以后缀基于目的而不是类型

  • 我正在实施这个 ERP 产品,命名约定非常有用,可以加强“咨询视图,使用 API 更新”的模式,避免在不仔细考虑业务逻辑的情况下直接更新表的诱惑。 (3认同)

l0b*_*0b0 10

tl;dr 它(很可能)添加了冗余信息,导致认知开销,因此应该被删除。

上下文是一个美妙的东西,尤其是在计算机系统中。脱离上下文,您不可能完全判断所调用的事物users是表、视图、存储过程还是其他东西。遗留(或只是写得不好)的系统和语言通常很难在阅读代码时确定上下文。例如,在bash中,你不能告诉什么function users没有做至少读功能的内容。在 Java 中,Map<Uid,UserDetails> users()它非常透明,您可以轻松挖掘细节。

把这个论点带到 SQL 表,什么时候让消费者users知道它是表还是视图是有用的?换句话说,是一种tbl前缀要告诉所有的消费者的东西,他们不知道需要知道什么?希望绝大多数消费者将针对它编写 DML 和 DQL 查询。对他们来说,它应该只是另一个数据源,无论是视图还是表,都应该与是否分区、存储在 HDD 或 SSD 上或任何其他技术细节一样相关。DBA 当然需要知道这些细节来运行一些罕见的 DDL/DCL 查询,但为了少数真正知道如何导航架构并获取所有技术细节的人而污染命名空间似乎适得其反。


Mic*_*een 9

关系数据库管理系统的特征之一是它将信息的逻辑表示与物理存储分开。前者是行集中的列。后者是存储卷上的文件。将一个映射到另一个是 DBMS 的工作。只有 DBA 或系统管理员才关心哪个硬件支持信息需求。消费者不需要,实际上也不应该意识到这些问题。

客户端也不应该关心如何构造行集。在这方面,基表、视图或函数都是相同的。每个简单地产生一组客户端使用的行和列。即使是一个简单的标量也可以被认为是一个单行单列的表。行/列模型是客户端和服务器之间的契约。

通过在人工制品的名称前加上它们的实现类型,这种关注点分离被打破了。客户端现在知道并依赖于服务器的内部结构。服务器编码的更改可能需要客户端返工。


Eri*_*rik 8

这里有很多我同意的答案,它们告诉您这不是一个非常有价值的命名约定。对于那些不相信其他答案的人,我将尝试证明许多其他答案所说的内容。


SELECT
  bar
  , fizz
  , buzz
FROM dbo.foo
Run Code Online (Sandbox Code Playgroud)

在上面的语句中,我从名为dbo.foo. 前缀的核心抱怨之一是他们不知道dbo.foo是表还是视图。当然,这是作为抽象的视图的优势之一,但我离题了。他们说我们应该像这样为对象添加前缀dbo.tblFoo。现在他们可以在上面的查询中看到对象是一个表(可能)。但是,如果我们编写该目标的功能等价物,它将看起来像这样。

SELECT
  bar
  , fizz
  , buzz
FROM dbo.Foo --table
Run Code Online (Sandbox Code Playgroud)

我怀疑评论看起来没有什么用,即使这是前缀有效地争论的内容。为了突出这个元数据注释注入的无用噪音,考虑一个更复杂的查询。

SELECT
  qc.occurances
  , i.employeeId
  , q.questionText
FROM dbo.questionCount /*Indexed view*/ qc WITH (NOEXPAND)
  INNER JOIN dbo.interviewer /*partitioned view*/ i ON i.employeeId = qc.interviewerId
  INNER JOIN dbo.question /*table*/ q ON q.id = qc.questionId
WHERE
  EXISTS (
           SELECT 
             1 
           FROM dbo.currentEmployees /*view*/ ce 
             INNER JOIN dbo.questionsAsked /*table*/ qa ON qa.candidateId = ce.candidateId
           WHERE
             ce.employeeId = i.employeeId
             AND
             qa.questionId = q.id
         )
  AND
  qc.occurances > 5;
Run Code Online (Sandbox Code Playgroud)

额外的评论是否使该查询更容易推理,或者它们只是增加了额外的噪音?在我看来,它们只是增加了额外的噪音并增加了零值。这就是反前缀者想要说的。此外,使用前缀实际上比那些注释更糟糕,因为如果您的数据模型需要调整,更新注释的成本远低于更新前缀表的名称。由于这些前缀是有代价的,而且它们不会传递有价值的信息,因此应该避免使用。

有些人引用的前缀的另一个优点是它可以在您的开发环境中赋予某种分组或排序。由于我们花费大量时间编辑代码,这对某些人来说可能是一个诱人的论点。然而,根据我的经验,现代开发环境提供了等效或更好的选项,不会用无用的元数据散布您的代码并限制您的灵活性。


Joh*_*ell 7

这已被多次介绍,但最著名的可能是美国 SQL 和关系数据库专家Joe Celko。我个人一直在网上接受他的一个咆哮(感到很荣幸),他将这些前缀称为“tibbling”,或者更准确地描述为“ skeuomorphism ”。

一般的想法是,这些前缀是很久以前的编码实践(可能是由于命名限制,例如对象名称的 8 字节限制),没有明显有用的原因传给几代程序员,除了它只是“方式完成了”。

公司、博主和程序员以他们自己的编码风格传递信息,有些风格可能比其他风格更“弗兰肯斯坦”。一家公司可能有一种“房子风格”,程序员被迫学习这种做法。

随着时间的推移,事情会坚持下去,即使它们最初被使用的原因现在已被弃用。“Tibbling”是关系数据库管理中最著名的例子之一。

总结一下:它不添加任何值,它在每个表名上正好添加了 4 个字节的存储空间,除了因为它在那里之外没有其他原因。它对现代 SQL Server 系统没有任何帮助,但如果它让您感觉更好,请继续使用它。

  • 由于这句话,我对这个答案投了反对票,“但如果它让你感觉更好,那就继续使用它。” 这是使用约定的*可怕*理由。 (8认同)
  • @JohnBell,但您可以不推荐它... (6认同)

小智 5

我的建议是你立即停止这样做。如果这让您感到不舒服,请在表名的末尾添加“_tbl” 。当然,由于已经提到的原因,也没有必要这样做。最初告诉你这样做的人给了你一些不好的建议。“这对我们组织的系统设置不当”的建议可能很糟糕,但在这种情况下,修复它是他的工作。还是不好的建议。