数据库设计 - 主键命名约定

时间:2010-10-14 13:46:51

标签: mysql database

我有兴趣知道人们在MySQL中命名数据库表主键的以下3种不同约定(以及为什么)?

- 示例1 -

表名:用户,
主键列名:user_id

- 示例2 -

表名:用户,
主键列名:id

- 示例3 -

表名:用户,
主键列名:pk_user_id

只想听听想法,或者在此过程中学到一些东西:)

感谢。

9 个答案:

答案 0 :(得分:10)

我会选择2.对我而言,“id”本身就足够了。 由于该表是User,因此“user”中的列“id”表示它是User的标识条件。

但是,我必须补充说,命名约定都是关于一致性的。 只要存在一致的模式并且它应用于整个应用程序,通常没有对错,这可能是命名约定有效性的更重要因素,以及它们使应用程序更容易理解的程度。因此保持。

答案 1 :(得分:9)

我总是更喜欢示例1中的选项,其中表名(冗余地)用在列名中。这是因为我更喜欢在JOIN中看到ON user.user_id = history.user_id而不是ON user.id = history.user_id

然而,在这个问题上,对于这个问题的重视一般似乎在Stackoverflow上对我不利,大多数人都喜欢这个例子。

顺便说一句,我更喜欢UserID和user_id作为列命名约定。我不喜欢键入下划线,并且使用下划线作为常见的SQL单字符匹配字符有时会有点混乱。

答案 2 :(得分:7)

ID是我认为最糟糕的PK名称。 TablenameID对报告的效果要好得多,因此在执行复杂的报告查询时,您不必为一堆名称相同的列添加别名。

我个人认为,如果列的含义相同,则只应将它们命名为相同的内容。客户ID与orderid不同,因此它们在概念上应具有不同的名称。当你有很多连接和复杂的数据结构时,当pk和fk具有相同的名称时,它也更容易维护。有ID列时,很难发现连接中的错误。例如,假设您加入了四个表,其中所有表都有一个ID列。在最后一次连接中,您意外地使用了第一个表的别名而不是第三个表。如果您使用OrderID,CustomerID等而不是ID,则会出现语法错误,因为第一个表不包含该列。如果您使用ID,它将很乐意错误地加入。

答案 3 :(得分:6)

我倾向于使用第一个选项user_id

如果您使用id,则通常最终需要在查询中过度使用别名。 如果你选择more_complicated_id,那么你必须缩写,或者你的空间不足,你就厌倦了输入这么长的列名。

2美分。

答案 4 :(得分:5)

我同意@InSane,只喜欢Id。这就是原因:

如果您有一个名为User的表,以及一个处理用户名称的列,您是将其称为UserName还是名称? “用户”似乎是多余的。如果您有一个名为Customer的表和一个名为Address的列,您是否调用CustomerAddress?

虽然我也看到了你在哪里使用UserId,然后如果你有一个带有用户外键的表,该列也将是UserId。这样可以保证命名的一致性,但IMO并没有给你带来太多的收获。

答案 5 :(得分:4)

回应Tomas'回答,假设评论表的PK也被命名为 id ,那么仍然会有歧义。

在回答问题时,示例1 获得了我的投票。 [表名] _id 实际上会消除歧义。

而不是

SELECT u.id AS user_id, c.id AS comment_id FROM user u JOIN comment c ON u.id=c.user_id

我可以简单地写

SELECT user_id, comment_id FROM user u JOIN comment c ON u.user_id=c.user_id

WHERE ON 中使用相同的ID名称没有任何含糊之处。它实际上增加了恕我直言。

答案 6 :(得分:2)

我一直很欣赏Justinsomnia对数据库命名约定的看法。请阅读:http://justinsomnia.org/2003/04/essential-database-naming-conventions-and-style/

答案 7 :(得分:1)

我建议示例2.这样外键和主键之间没有歧义,如示例1中所示。例如,您可以这样做

SELECT * FROM user, comment WHERE user.id = comment.user_id

简洁明了。

第三个例子在设计中是多余的,其中所有id都用作主键。

答案 8 :(得分:1)

好的,所以忘记示例3 - 它只是简单的愚蠢,所以它介于1和2之间。

PK学派的身份(2)

drop table if exists customer;
create table customer
(
id int unsigned not null auto_increment primary key, -- my names are id, cid, cusid, custid ????
name varchar(255) not null
)engine=innodb;

insert into customer (name) values ('cust1'),('cust2');

drop table if exists orders;

create table orders
(
id int unsigned not null auto_increment primary key, -- my names are id, oid, ordid
cid int unsigned not null -- hmmm what shall i call this ?
)engine=innodb;

insert into orders (cid) values (1),(2),(1),(1),(2);

-- so if i do a simple give me all of the customer orders query we get the following output

select
 c.id,
 o.id
from
 customer c
inner join orders o on c.id = o.cid;

id  id1 -- big fan of column names like id1, id2, id3 : they are sooo descriptive
==  ===
1     1
2     2
1     3
1     4
2     5

-- so now i have to alias my columns like so:

select
 c.id as cid, -- shall i call it cid or custid, customer_id whatever ??
 o.id as oid
from
 customer c
inner join orders o on c.id = o.cid; -- cid here but id in customer - where is my consistency ?

cid oid 
==  ===
1     1
2     2
1     3
1     4
2     5

PK / FK名称学校的tablename_id前缀(1)

(随意使用缩写形式的tablename,即cust_id而不是customer_id)

drop table if exists customer;
create table customer
(
cust_id int unsigned not null auto_increment primary key, -- pk
name varchar(255) not null
)engine=innodb;

insert into customer (name) values ('cust1'),('cust2');

drop table if exists orders;
create table orders
(
order_id int unsigned not null auto_increment primary key,
cust_id int unsigned not null 
)engine=innodb;

insert into orders (cust_id) values (1),(2),(1),(1),(2);

select
 c.cust_id,
 o.order_id
from
 customer c
inner join orders o on c.cust_id = o.cust_id; -- ahhhh, cust_id is cust_id is cust_id :)

cust_id order_id
======= ========
1           1
2           2
1           3
1           4
2           5

所以你看到tablename_前缀或缩写tablename_prefix方法是最多的 一致而轻松的最佳惯例。