【问题标题】:How do you avoid column name conflicts?如何避免列名冲突?
【发布时间】:2011-07-02 17:00:24
【问题描述】:

我最近被分配了创建拍卖系统的任务。在我的工作中,我遇到了很多情况,其中包含连接的 SQL 查询由于列名不明确而无法执行。考虑一下这个(简化的)拍卖表结构:

auction:

  • id
  • name
  • uid(创建拍卖的用户 ID)

item:

  • id
  • name
  • uid(添加商品的用户 ID)
  • aid(该物品可用的拍卖 ID)
  • price(原价)

user:

  • id
  • name

bid:

  • id
  • uid(出价用户的 ID)
  • iid(涨价商品)
  • price(报价)

如您所见,有许多列的名称相互冲突。加入这些表需要使用一些可以消除歧义的措施。

我可以想到两种方法来做到这一点。首先是重命名列,在所有列前加上一个缩写的表名,这样拍卖ID将变为a_id,项目ID将变为i_idbid表中的项目ID将变为b_i_id。这非常可靠,但会降低列名的可读性。

我能想到的另一种方法是编写显式查询:

SELECT `bid`.`id`, `user`.`name`, `bid`.`price`
FROM `bid`
JOIN `item` ON `item`.`id` = `bid`.`iid`
JOIN `user` ON `user`.`id` = `bid`.`uid`
JOIN `auction` ON `auction`.`id` = `item`.`aid`
WHERE `bid`.`price` > `item`.`price`
AND `auction`.`id` = 1
GROUP BY `user`.`id`
ORDER BY `bid`.`price` DESC;

这是可读且明确的,但需要大量额外的击键。

我使用第二种方法,但也许您在类似情况下成功使用过其他方法?如何避免 SQL 查询中的列名冲突?

【问题讨论】:

  • 如果keystrokes 是您编程时的一个顾虑,您需要重新考虑您的职业道路!
  • @Richard: 好的,你得到了我这个,这句话值得+1 :)
  • 去掉反引号`,这些与SQL无关(检查标准!)并节省一些击键。
  • @RichardTheKiwi 不仅仅是keystrokes;它使视图变得僵硬。在将列添加到表中但视图不会随之更新的情况下,它可以很容易地产生静默问题。我知道理论上每个人都应该一直输入所有字段,但人们经常使用自动为他们映射列的程序,例如PowerBI、EntityFramework等

标签: mysql sql conflict


【解决方案1】:

我遇到过MySQLSyntaxErrorException:

您的 SQL 语法有错误;检查手册 对应于您的 MySQL 服务器版本,以便使用正确的语法 接近'等级

执行以下查询后:

插入 my_table (rank) 值 (1);

因为rank 列名与sql 关键字rank 冲突。

解决方案:

我在rank 列名中添加了反引号,问题已解决:

插入 my_table (`rank`) 值 (1);

解决问题的另一种方法是使用表名代替反引号

插入 my_table (my_table.rank) 值 (1);

【讨论】:

    【解决方案2】:

    也可以在表名旁边定义表列:

    SELECT P.*,T.name AS type FROM <TABLE-A> AS P LEFT JOIN <TABLE-B> AS T ON P.id=T.id
    

    【讨论】:

      【解决方案3】:

      更改您的命名约定,以便每个数据元素在架构中都有一个唯一的名称,例如auction_idbid_iduser_id 等。理想情况下,数据元素的名称不会在表之间更改,但有时您需要添加限定符来创建同义词,例如adding_user_idbidding_user_id 如果user_id 在同一个表中出现两次。您应该在数据字典中记录数据元素名称及其同义词。

      【讨论】:

      • 同意,但是当大多数人陷入这种困境时,他们已经深入到一个没有此类文档的系统中,这意味着要花费数周的时间来修复其他人创建的问题 =(
      【解决方案4】:

      黄金法则是,如果您曾经使用过多个表,请为这些表设置别名,并为所有列显式设置别名。

      这种一致性会让你更深入地了解力量,年轻的学徒。

      【讨论】:

        【解决方案5】:

        您的方法是正确的,但您也可以为您的表提供别名:

        SELECT a.* FROM TableA A
        

        在这里您可以将 TableA 简称为 A。

        【讨论】:

          【解决方案6】:

          我的经验是,从长远来看,额外击键所带来的好处超过了到目前为止键入它们所需的短时间,最迟在您需要时看看你一年前写的一个查询。

          【讨论】:

            【解决方案7】:

            You need to use AS alias.

            您可以使用别名为表或列指定另一个名称。如果您有很长或很复杂的表名或列名,这可能是一件好事。

            别名可以是任何名称,但通常很短。

            【讨论】:

            • 您不需要AS 来使用别名。
            • @Frank Heikens:我知道,但使用该关键字是一种很好的做法 :)
            【解决方案8】:

            您可以尝试在表名上使用aliases 吗?

            select * from table1 as T1
            join table2 as t2 on (t1.key=t2.foreignkey)
            

            【讨论】:

            • 这是我做的,但是在多次嵌套join之后我仍然感到同样的痛点。
            猜你喜欢
            • 2014-03-12
            • 2015-03-21
            • 1970-01-01
            • 1970-01-01
            • 2013-03-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多