【问题标题】:Is prefixing each field name in a table with abbreviated table name a good practice?用缩写表名为表中的每个字段名添加前缀是一种好习惯吗?
【发布时间】:2010-10-02 16:23:21
【问题描述】:

您是否在表中的每个字段前面加上缩写的表名?

例子:

Table: User

Fields:
user_id
user_name
user_password

或者您是否对字段命名最少?

Fields:
id
name
password

如果您两者都使用过,那么从长远来看,您认为哪种格式对您的帮助最大?

编辑:这个问题似乎没有明确的答案,双方都提出了很好的观点。但是我将这个问题保持开放太久了,也许是时候将一个答案标记为已接受了。因此,我将投票数最高的标记为已接受。

【问题讨论】:

  • 如果您为简单的应用程序设计表,则不需要为字段使用前缀。但是,如果您想处理大型企业应用程序,并且使用了太多的连接并编写了大量的 SQL 查询,那么它将对您有很大帮助并简化一切。

标签: database-design schema


【解决方案1】:

不要那样做。这是多余的,从长远来看会导致挫败感。

可以应用它的唯一字段可能是id,因为user_id 显然是用户的ID,它可以简化SQL 中的连接编写。但我什至不会那样做。

【讨论】:

  • +1:干燥 - 不要重复自己。列名已经属于表,表的内容从上下文中是显而易见的。
  • 由于我们经常进行连接,如果连接的表有名称冲突,您将倾向于 RY 更多,因为太多而无法别名。即使对于 user_id 也要这样做
  • +1 我在这里给出了相同的答案:stackoverflow.com/questions/529863/…
  • 使用user_id 代替id 允许您在连接中使用USING 而不是ON
  • 使用user_id可能也是一个好主意,具体取决于您使用的工具。在我上一份工作中,我们使用 SAS Enterprise Guide 进行数据分析。这个工具的默认行为是希望基于共享列名连接表。由于我们所有的表都有一个 id 列,我们必须先删除自动生成的连接,然后才能定义我们真正想要的连接。
【解决方案2】:

如果你这样做,你最终会写出这样的查询:

SELECT user.user_name, user.user_password, user.user_firstname ...

而不是

SELECT user.name, user.password, user.firstname

所以 IMO 对您的问题的回答非常明确。

【讨论】:

  • 为什么你不能只写 SELECT user_name, user_password FROM.... 如果只有 user 表有 user_ 前缀,那么你就不必明确地说 user.whatever
  • 即使您只是从不同的表中选择字段!它们可能具有相同的列名,因此您需要明确要从哪个表中选择哪一列!
  • 和连接它变得更加成问题,因为您可能希望在两个表中具有相同的列名......
  • -1 用于制作一个人为的示例,使 tablename_fieldname 看起来很糟糕。当您只查询一个表时,谁会在字段前面重新指定 table.
  • 这只是一个例子,你只查询一个表的频率是多少???
【解决方案3】:

你不再需要这样做了,你真的不应该这样做。 saua pointed out 的唯一例外可能是 ID 字段,用于寻求连接的清晰度。

字段名称与表名前缀的概念来自旧系统的旧时代,当时整个数据库中的每个字段都需要是唯一的。

因此,除非您处理的是要求整个数据库中的每个字段都具有唯一名称的遗留系统;不要这样做。

【讨论】:

  • 恕我直言,ID 字段唯一需要前缀的时候是外键。在您的联接中,无论如何您都应该为表格添加前缀,因此冲突/清晰度问题应该会消失。
  • Harper:这就是人们经常给主键加上前缀的确切原因——所以它在每个表中都是相同的列名,无论 PK 还是 FK
【解决方案4】:

我不会这样做。如果您想要某个字段属于哪个表的信息,您可以随时将查询编写为

select user.id, user.name from user where ...

但假设您出于某种原因决定重命名您的一张表(可能从“用户”更改为“客户”)。您还必须重命名所有字段以保持一致。

我的观点:你应该这样做没有很好的理由,不这样做有几个很好的理由。

【讨论】:

  • 如果有一个令人信服的理由重命名您的表和字段(user_id 到 customer_id),就这样吧,连同 pk_newtablename、ck_newtablename__limit_loan、fk_newtablename__primary 等。如果表的新名称远离原来的目的,最初的数据库设计不好。
  • 我同意。但以我的经验,最初的数据库设计通常远非完美......
【解决方案5】:

将前缀放在列名上可能是一个好习惯。如果您正在处理一个正式的(并且可能是大型的)数据库并且您正在关注 ISO 11179(特别是数据元素名称的概念),那么最好将完整的三个(或四个)部分名称放入:对象 - 属性 - 表示术语。 (第四个可选部分是限定符。)例如,“user_first_name”。这样,您的数据字典和数据库模式之间就会保持一致。由于已经评论过的原因,我不会对较小的数据库执行此操作,但在复杂的架构中,这会降低一些错误风险。

【讨论】:

    【解决方案6】:

    我们通常也不使用缩写表前缀,我也不建议这样做。

    但我们会在一种情况下进行:保留字段

     e.g. OH_Reserve_Field_Alpha3 in table ORDER_HEADER
    

    简短背景:我们的数据库有 250 多个表,我们在其中的大部分表中放置了保留列,以用于未来的功能实现。可以想象,如果没有前缀,您最终会在整个代码中拥有 50 个含义完全不同但名称相同的 Reserve_Field_Alpha3。像现在这样已经很难了,但是没有前缀会更糟。

    【讨论】:

      【解决方案7】:

      我建议坚持使用表别名,例如:

      SELECT 
          user.id,
          user.email, 
          user.firstname, 
          user.secondname,
          avatar.filename
      FROM
          pain_in_the_butt_table_name user
      LEFT JOIN
          table_with_the_avatars avatar
      ON avatar.user_id = user.id
      

      优点:

      • 维护一个易于理解的您选择的字段列表,以及您从哪些表中获取这些字段

      • 避免输入冗长或难以理解的表名,并用简短易懂的名称替换它们(创建表时应该这样做)

      • 执行可读的联接(您的示例应为:

      LEFT JOIN table_with_the_avatars.user_id ON user.user_id = table_with_the_avatars.avatars_user_i

      • 创建更短的别名,在我的示例中,这意味着 u 代替用户,a 代替头像,从而缩短您的查询

      【讨论】:

        【解决方案8】:

        当我将字段“序数”添加到表中时,我喜欢添加前缀,这样我就不必在 JOINS 中为其他表中的序数字段设置别名。 有时它对 JOINS 很方便……不确定我是否看到了其他好处。

        MediaWiki(维基百科软件)使用该约定。下载源代码。 它们将自己限制为两个字符的前缀。

        我不推荐这种做法。对于大多数数据库来说,这不是必需的。

        【讨论】:

          【解决方案9】:

          就个人而言,在“用户”表中,我的列将只是“id”。

          但是不同表上指向该列的任何外键列,我都会将该列称为“user_id”。

          所以你可能会得到这样的结果:

          select  *
          from    order
                  inner join user
                      on user.id=order.user_id
          

          【讨论】:

            【解决方案10】:

            以这种方式(最少)命名字段是可以的,但对于主键和标题/名称。如果您始终将所有主键命名为 ID,并将名称命名为 Name,则构造查询将退化为多余的别名:

            select i.id as invoice_id
            
            v.id as vendor_id, p.id as product_id, 
            v.name as vendor, p.name as product, b.name as branch, c.name as parcel,
            
            i.total_amount,
            i.discount,
            i.invoice_date
            
            from invoice i
            join product p on i.product_id = p.id
            join vendor v on i.vendor_id = v.id
            join branch b on i.branch_id = b.id
            join parcel c on i.parcel_id = c.id
            

            由于连接表格和显示实体的标题/名称是常态而不是例外,我以完整形式命名我的主键,对于标题/名称字段,与表格名称相同。

            create table product
            (
            product_id uuid not null, -- primary key
            product text not null,
            bar_code text not null default '',
            rfid_code text  not null default '',
            current_qty int default 0
            );
            
            create table vendor
            (
            vendor_id uuid not null, -- primary key
            vendor text not null,
            is_active boolean not null default true
            );
            
            create table branch
            (
            branch_id uuid not null, -- primary key
            branch text not null,
            sub_branch_of_id uuid,
            current_sales money not null default 0,        
            );
            
            create table user
            (
            user_id uuid not null, -- primary key
            user text not null,
            password text not null default ''
            );
            

            因此您的查询不会有多余的别名:

            select i.invoice_id, p.product_id, v.vendor, p.product, b.branch, c.parcel,
            
            i.total_amount,
            i.discount,
            i.invoice_date
            
            from invoice i
            join product p on o.product_code = p.product_code
            join vendor v on o.vendor_code = v.vendor_code
            join branch b on o.branch_code = b.branch_code
            join parcel c on o.parcel_code = c.parcel_code
            

            【讨论】:

              【解决方案11】:

              出于所有给出的原因,我认为这不是一个好主意。此外,您不会在类中的所有方法前面加上类名,对吗?那么为什么要对数据库对象这样做呢?

              【讨论】:

              • 因为表是用来连接的,类不是。与表发生名称冲突的可能性高于类。
              【解决方案12】:

              前缀变体只是需要更长的时间来编写,并且使读取具有许多字段的 sql 语句变得更加困难。

              即使您从多个表中进行选择,这也只会给您带来不必为不明确的字段添加表名前缀的好处。但是

              SELECT user.name, image.name FROM user, image
              

              没有太大区别
              SELECT user_name, image_name FROM user, image
              

              查询中没有歧义字段的好处很快就会被每次使用列名时必须输入表名的开销所消耗。

              【讨论】:

              • 您最终会为以下字段(尤其是在报告中)添加别名:SELECT user.name, image.name FROM user, image。为什么不为自己省力呢?要消除相同字段名称的歧义,您必须在 PHP、C#、Java 等上为它们起别名。 SELECT user.name as user_name, image.name as image_name FROM user, image
              • @Hao:所以你想通过增加对所有查询的投资来节省一些查询的工作量?
              • 同意。报告是所有计划的底线。所以加入表格是我们经常做的事情。我们经常需要对这些字段进行别名/消除歧义,以便将它们映射到数据集、关联数组、网格视图、报告等
              • 最好将这些全名放在表级别,而不是在查询中不断地给它们起别名。
              【解决方案13】:

              这是一个很棒的练习:

              1. 您会看到每个字段的含义,在 至少在它是什么领域。你 不知道amount 是什么意思 (transactions, incomes) — 除非 他们是xac_amountinc_amount。大多数查询工具都可以 不输出别名连同 字段名称。
              2. 您可以使用表别名,例如 当然。但是 SQL 不需要它们, 根据墨菲定律,如果不是 必填,不会使用。有 没有标准,所以一位开发人员会 使用 x 作为别名 transaction,另外一个会用 tran 等等。

              其实前缀只是强制的表别名,所以可以很方便的看到哪个字段属于哪个表。

              【讨论】:

              • 不确定是否严重:\
              【解决方案14】:

              如果您为每个表使用唯一前缀,那么

              • 不需要为连接使用别名(自连接除外)
              • 数据库中所有列的名称都应该是唯一的
              • 您可以轻松地从列名本身识别表(从 输出或选择查询)

              【讨论】:

                猜你喜欢
                • 2020-02-02
                • 2017-06-16
                • 1970-01-01
                • 2011-09-06
                • 2017-08-09
                • 2017-04-07
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多