【问题标题】:Column prefixes in tables表中的列前缀
【发布时间】:2014-07-25 14:44:42
【问题描述】:

首先我需要指出我阅读了Database columns type prefix,但这不是同一个问题。

很久以前,和我一起工作的人告诉我,在我参与的项目中,所有列都需要有唯一的前缀。

例如对于users 表,我使用前缀u_,因此所有列都命名为u_idu_name 等等。与所有其他表相同,例如 products 它将是 p_ 前缀。

这样做的原因是 SQL JOINS 更容易 - 如果要连接 2 个或更多表,则所有列都将具有唯一的名称。老实说,到目前为止我一直在使用这个建议,但实际上我不知道它是否被很多人使用,或者它真的很有用。

您对此有何看法?您是否使用这样的列命名,或者您认为这完全没有必要并且浪费时间? (显示数据时,如果不使用函数或 foreach 删除,则需要使用前缀)

编辑

以防万一更多解释

假设我们有带有字段 id、name 的 users 表和带有字段 id、name、user_id 的地址表

如果使用此方法,如果我们想获取所有可以做的字段:

SELECT * 
FROM users u 
LEFT JOIN address a on u.u_id = a.a_user_id

如果我们不为列使用前缀,我们应该使用:

SELECT u.id AS `u_id`, 
  u.name AS `u_name`, 
  a.id AS `a_id`, 
  a.name AS `a_name`, 
  a.user_id 
FROM users u 
LEFT JOIN address a on u.id = a.user_id

当然假设我们想使用列作为名称而不是数字索引 0,1 等等(例如在 PHP 中)

EDIT2

似乎我没有充分解释问题出在哪里 - 当然在 MySQL 中,在这两种情况下一切正常,这不是问题。

但问题是当我想在编程语言中使用数据时,例如 PHP。如果我使用:

<?php

$db = new mysqli('localhost','root','','test_prefix');

$result = $db->query("SELECT * FROM `user` u LEFT JOIN `address` a ON u.id = a.user_id ");
while ($data = $result->fetch_array()) {
    var_dump($data);        
}

我明白了:

array(8) { [0]=> string(1) "1" ["id"]=> string(1) "1" 1=> string(5) "Frank" ["name"]=> string(3) "USA" [2]=> string(1) "1" [3]=> string(3) “美国”[4]=>字符串(1)“1”[“user_id”]=>字符串(1)“1”}数组(8){ [0]=>字符串(1)“2”[“id”]=>字符串(1)“2”1=>字符串(4)“约翰” ["name"]=> string(6) "加拿大" [2]=> string(1) "2" [3]=> string(6) "加拿大" [4]=> 字符串(1) "2" ["user_id"]=> 字符串(1) "2" }

而该查询的 PhpMyAdmin 结果如下所示:

在 PHP 中获取所有数据,但我可以使用数字索引访问数据:$data[0]$data[1],这不是很方便。我不能使用用户名,因为在$data['name'] 中只有地址名称,在 id 中相同。如果我同时使用以下任何一种:列的别名或列的前缀,我将能够使用字符串索引来访问数据,例如 $data['user_name'] 访问用户名和 $data['address_name'] 访问地址名称。

【问题讨论】:

    标签: mysql sql database database-schema prefix


    【解决方案1】:

    我认为这很愚蠢。实际上,您最终会在所有查询中使用它们的表名(或“标识符”)作为前缀,即使没有歧义。

    如果你比较:

    SELECT t1_col1, t2_col1
    FROM t1, t2;
    

    ...与:

    SELECT t1.col1, t2.col1
    FROM t1, t2;
    

    ...那么建议可能看起来很明智。

    现在比较:

    SELECT t3_col3, t4_col4 FROM t3, t4;
    

    ...与:

    SELECT col3, col4
    FROM t3, t4; -- assuming col3 exists only in t3, and col4 only in t4
    

    现在好处在哪里?

    人们仍然可以争辩说,一两个字母的前缀仍然比长表名更可取:

    SELECT t1_col1, t2_col1
    FROM very_long_table_name1, very_long_table_name2;
    

    但既然可以,为什么还要用前缀呢:

    SELECT t1.col1, t2.col1
    FROM very_long_table_name1 AS t1, very_long_table_name2 AS t2;
    

    实际上,在某些情况下前缀可能会派上用场(在我看来,方便并不意味着推荐)。例如,当结果集中的多个列具有相同的名称时,某些驱动程序(我认为是旧 PHP)可能会感到困惑(因为它们将行作为按列名称索引的数组返回)。这个问题仍然可以通过给结果集中的列设置别名来解决。

    【讨论】:

    • 我想主要的想法是避免名称冲突,所以如果我在加入表格时需要 id,我不需要将 t1.id 写为 t_id, t2.id AS t2_id 但就是这样为什么我问这个问题是为了了解你的意见。来自我的 +1
    • 我避免在我的表中使用名为 id 的列的原因之一是为了避免这种混乱。
    • @MarcinNabiałek 我不确定我是否完全理解您的观点。您永远不必为您的列设置别名:您可以在没有别名的情况下编写 SELECT t1.id, t2.id FROM t1 JOIN t2 ON t1.id = t2.id(即,您可以在查询中的任何位置将这些列称为 t1.idt2.id)。
    • @RandomSeed 抱歉,我好像还不够清楚。请查看我的问题中的 Edit2
    • 我明白了。这就是我试图用我的答案的第二部分来涵盖的内容。您可以通过这样的列别名来解决此问题:SELECT user.name AS user_name, country.name AS country_name。虽然我不喜欢在表定义中为 all 列名添加前缀的想法,但可能可以接受为 那些 列名添加前缀,否则这些列名将具有与另一个表中的另一个列同名。在需要时,我仍然更喜欢 别名列,但我们在这里进入了一个灰色区域。
    【解决方案2】:

    我认为这是不必要的,但是以现有项目的一致性为名,您应该维护它或重构整个数据库。

    为什么它是不必要的?看看下面的查询,它说明了如何从数据库中获取任何你想要的东西

    我也认为它更具可读性,并且别名工作正常

    如果您的列名发生冲突而不能很好地与某些驱动程序一起使用,您可以使用 AS 语句来获取该特定字段,因为您可以两次加入同一个表,但无论如何都会给您带来完全相同的问题使用前缀

    SELECT 
      `m`.*, 
      `u1`.`username` AS `sender`, 
      `u2`.`username` AS `receiver`
    FROM `messages` `m` 
    INNER JOIN `users` `u1` ON `m`.`sender` = `u1`.`id`
    INNER JOIN `users` `u2` ON `m`.`receiver` = `u2`.`id`
    

    【讨论】:

    • +1,在处理遗留代码时,一致性比良好做法更重要
    【解决方案3】:

    我什至会说这是一种危险的做法,因为它鼓励草率的编码。

    假设您有 2 个表:用户和使用情况

    select u_type, us_name
    from User
    inner join Usage on u_id = us_id
    

    哪个字段来自哪里?您需要查看表结构来确定它,并且在这些情况下做出假设可能很诱人。

    select u.type,us.name
    from User us
    inner join Usage u on us.id = u.id
    

    现在您可以将所需的所有信息摆在您面前。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      • 1970-01-01
      • 2023-02-04
      • 1970-01-01
      • 2012-11-25
      • 1970-01-01
      相关资源
      最近更新 更多