[英]Database design - primary key naming conventions
我很想知道人們對以下 3 種在 MySQL 中命名數據庫表主鍵的不同約定有何看法(以及為什么)?
-示例 1-
表名:用戶,
主鍵列名:user_id
-示例 2-
表名:用戶,
主鍵列名:id
-示例 3-
表名:用戶,
主鍵列名:pk_user_id
只是想聽聽想法,也許在這個過程中學到一些東西:)
謝謝。
我會選擇2.對我而言,“id”本身就足夠了。 由於該表是User,因此“user”中的列“id”表示它是User的標識條件。
但是,我必須補充說,命名約定都是關於一致性的。 只要存在一致的模式並且它應用於整個應用程序,通常沒有對錯,這可能是命名約定有效性的更重要因素,以及它們使應用程序更容易理解的程度。因此保持。
我總是更喜歡示例1中的選項,其中表名(冗余地)用在列名中。 這是因為我更喜歡在JOIN中看到ON user.user_id = history.user_id
不是ON user.id = history.user_id
。
然而,在這個問題上,對於這個問題的重視通常似乎在我的Stackoverflow上反對,大多數人都喜歡這個例子2。
順便說一下,我更喜歡UserID到user_id作為列命名約定。 我不喜歡鍵入下划線,並且使用下划線作為常見的SQL單字符匹配字符有時會有點混亂。
在我看來,ID是您可以擁有的最糟糕的PK名稱。 TablenameID對報告的效果要好得多,因此在執行復雜的報告查詢時,您不必為一堆名稱相同的列添加別名。
我個人認為,如果列的含義相同,那么它們的名稱應該相同。 客戶ID與orderid不同,因此它們在概念上應具有不同的名稱。 當你有很多連接和復雜的數據結構時,當pk和fk具有相同的名稱時,它也更容易維護。 有ID列時,很難發現連接中的錯誤。 例如,假設您加入了四個表,其中所有表都有一個ID列。 在最后一次連接中,您意外地使用了第一個表的別名而不是第三個表。 如果您使用OrderID,CustomerID等而不是ID,則會出現語法錯誤,因為第一個表不包含該列。 如果您使用ID,它將很樂意錯誤地加入。
我傾向於使用第一個選項user_id
。
如果你使用id
,通常最終需要在查詢中過多地使用別名。 如果你使用more_complicated_id
,那么你必須縮寫,或者你沒有空間,你厭倦了輸入這么長的列名。
2美分。
我同意@InSane並且喜歡Id
。 這就是為什么:
如果您有一個名為User的表,以及一個處理用戶名稱的列,您是將其稱為UserName還是名稱? “用戶”似乎是多余的。 如果您有一個名為Customer的表和一個名為Address的列,您是否調用CustomerAddress列?
雖然我也看到了你將使用UserId
,然后如果你有一個帶有外鍵給User的表,那么該列也將是UserId。 這樣可以保證命名的一致性,但IMO並沒有給你帶來太多的收益。
為了回應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名稱沒有任何含糊之處。 它實際上增加了恕我直言。
我一直很欣賞Justinsomnia對數據庫命名約定的看法。 請閱讀: http : //justinsomnia.org/2003/04/essential-database-naming-conventions-and-style/
我建議示例2.這樣,外鍵和主鍵之間沒有歧義,如示例1中所示。例如,您可以這樣做
SELECT * FROM user, comment WHERE user.id = comment.user_id
這簡潔明了。
第三個例子在設計中是冗余的,其中所有id都用作主鍵。
好吧,所以忘記例子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方法是最一致和最容易的最佳約定。
我不同意大多數答案所指出的 - 只是保持一致。 但是,我只是想補充一點,使用user_id
的冗余方法的一個好處是允許使用USING
語法糖。 如果不是因為這個因素,我想我個人會選擇避免冗余。
例如,
SELECT *
FROM user
INNER JOIN subscription ON user.id = subscription.user_id
對比
SELECT *
FROM user
INNER JOIN subscription USING(user_id)
這不是一個瘋狂的顯着差異,但我發現它很有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.