首先,我需要指出我读过Database columns type prefix,但这不是同一个问题。
很久以前,与我合作的人告诉我,在我参与的项目中,所有列都需要有唯一的前缀。
例如对于users
表,我使用前缀u_
,因此所有列都命名为u_id
,u_name
,依此类推。与products
的所有其他表格相同,它将是p_
前缀。
原因是SQL JOINS更容易 - 如果要连接2个或更多表,所有列都将具有唯一的名称。说实话,我到目前为止已经使用过这个建议,但实际上我不知道你们中的许多人是否使用过这个建议,或者它真的非常有用。
您对此有何看法?您是否使用此类列命名或者您认为这完全没必要且浪费时间? (当显示数据时,如果不使用函数或foreach删除它们,则需要使用前缀)
修改
以防更多解释
假设我们的用户表包含字段id,名称和地址表,其中包含字段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] =&gt; string(1)“1”[“id”] =&gt; string(1)“1”1 =&gt;串(5) “Frank”[“name”] =&gt; string(3)“USA”[2] =&gt; string(1)“1”[3] =&gt;串(3) “USA”[4] =&gt; string(1)“1”[“user_id”] =&gt; string(1)“1”} array(8){ [0] =&GT; string(1)“2”[“id”] =&gt; string(1)“2”1 =&gt; string(4)“约翰” [ “名称”] =&GT; string(6)“Canada”[2] =&gt; string(1)“2”[3] =&gt;串(6) “加拿大”[4] =&gt; string(1)“2”[“user_id”] =&gt; string(1)“2”}
而该查询的PhpMyAdmin结果如下:
在PHP中获取所有数据,但我可以使用数字索引访问数据:$data[0]
,$data[1]
,这不是很方便。我无法使用用户名,因为在$data['name']
中只有地址名称,ID相同。如果我使用以下两者中的任何一个:列的别名或列的前缀我将能够使用字符串索引访问数据,例如$data['user_name']
访问用户名,$data['address_name']
访问地址名称。
答案 0 :(得分:4)
我相信这是愚蠢的。实际上,即使没有歧义,您实际上也会在所有查询中使用其表名(或“标识符”)为所有列添加前缀。
如果你比较:
SELECT t1_col1, t2_col1
FROM t1, t2;
... with:
SELECT t1.col1, t2.col1
FROM t1, t2;
......然后推荐可能显得合情合理。
现在比较:
SELECT t3_col3, t4_col4 FROM t3, t4;
... with:
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)可能会感到困惑(因为它们将行作为按列名索引的数组返回)。仍然可以通过对结果集中的列进行别名来解决该问题。
答案 1 :(得分:3)
我认为这是不必要的,但在现有项目的一致性名称中,您应该维护它或重构整个数据库。
为什么不必要?那么看看下面的查询,它说明了如何从数据库中获得任何你想要的东西
此外,我认为它更具可读性,并且联盟正常运作
如果您的列名称发生冲突,但是对于某些驱动程序不能很好地工作,您可以使用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`
答案 2 :(得分:1)
我甚至说这是一种危险的做法,因为它鼓励人们编写草率。
假设您有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
现在,您可以在您面前获得所需的所有信息。