邏輯主鍵和聯合主鍵,一定要討論清楚!


轉自於:http://blog.csdn.net/haizhongyun/article/details/8056578

 

關於本文一些詞的說明:

單一主鍵:邏輯主鍵
復合主鍵:聯合主鍵,業務主鍵

 

今天在做項目的數據庫設計時,突然發現自己在表的主鍵設置方面太過片面,對於邏輯主鍵和聯合主鍵的理解也很少。索性上網百度了一下,看到了一些論壇中的兄弟們的討論,其中很多的分析讓我頓時清醒了很多。下面開始貼上一些人的觀點和分析,如果原作者看到本文,發現有不妥之處,請郵件告之。
 
網友goldrain說:
我倒不反對業務主鍵,但只指單一字段做主鍵,比如很多登陸系統,常就用loginName做用戶表主鍵,而且這么做很方便,我覺得只要是值唯一而且不改動的字段就可以做主鍵; 不過覺得聯合主鍵確實多余,這時用單一字段的邏輯主鍵取代聯合主鍵,對定位記錄的速度,對開發特別是hibernate開發會很方便; 我的觀點都是從自己開發方便角度講的.  
網友magician說:
我覺得邏輯主鍵和聯合主鍵用途不一樣:

如一個囚犯,進監獄就會給他一個邏輯主鍵,比如9527,但他外面混的朋友可能並不知道這個邏輯主鍵,而只有他的一些其他信息,比如姓名、年齡、外貌、所做的事情等等,這些感觀上的東西構成的可以認為是聯合主鍵。

如何評價這兩者誰好?我只能說,應用范圍不一樣。但不可否認,9527非常清晰!(當然我不願意人家這樣叫我.......) 

還有就是,你說用聯合主鍵做出來的東西運行得很好,所以你沒有道理要用邏輯主鍵。從你的實際情況而言,你這么說沒錯,但從邏輯思維的角度,你大錯而特錯:存在並不一定合理。不過在你自己還沒有找到使用邏輯主鍵的理由之前,我完全贊同你不要去修改現有系統這一英明的決定。 

再者,浪費很多空間?呵呵,我不認為一個類似於銀行這樣系統還會在於有一個字段引起的空間問題,假如這個字段給你帶來的是設計的合理和操作的快捷的話,請注意我用的是假如。當然,你可以更感性的了解一些數據,看看每個表多一個int字段會帶來多大的空間上的損失。我覺得空間這個東西,不是在這個層面需要考慮的問題。其實,我現在在做任何系統的設計,都不會考慮硬件空間的問題。 

至於更具體,比如對你們的系統性能究竟有多大影響,設計上有多大影響,現有系統改動量有多大,那是你應該考慮的問題。

另:Hibernate不一定要用邏輯主鍵  再另:不一定要用Hibernate!
 
網友xiaoyu說:
用邏輯還是業務,隨便你的,不過舊系統是不要用HB,HB也支持復合主鍵. 

主要是作了主鍵后就不能修改,這個蠻麻煩的.....唉.. 

記得那年,公司有出了一個主意,想要一個定單的系統,於是我就去調研(公司只有我一個開發員,客戶就是下面的員工),我說產口是不是有一個固定的產品號,是不是不會重復的(好象地球人都知道),那定單是不是有一個訂單號,也是固定的,不會重復,她們回答的時候是多么爽快呀(好象在逗小孩子). 

我就用Access建了表(就公司用,所以沒有選擇其它的數據庫),主鍵:用了產品號,用了訂單號.又因為她們超喜歡excel,就用了VBA..... 

系統運行了一段時間,后來產品的編號要改掉了,全部的產品號要在前面多加個LP開頭的.....我頓時..........@#$%^&*( OK,我只好用insert into XXXX (select XXX) (還是產品號為主鍵). . . 網友xj2ee說:
1、從純數據庫設計的角度來看: 
使用業務主鍵是自然的選擇,但如果業務發生變化引起業務主鍵的變化怎么辦?(xiaoyu舉的例子),所以引入邏輯主鍵id(當然不是每張表都要),浪費空間之說我認為是沒有必要考慮的,存儲技術的發展能容忍這點小浪費。而且單一的id在多表關聯時,顯然比復合主鍵有更好的性能。 
2、從WEB應用開發的角度來看: 
用邏輯主鍵你只需要在頁面和后台之間傳遞一個單一的參數,簡化了開發工作,而且有較高的查詢效率。 
3、從Hibernate應用的角度來說: 
復合主鍵需要更多的處理,性能不高,所以Hibernate不提倡用復合主鍵。

 

 

補充網上一些其他討論:

多對多關系建立中間表一定要用聯合主鍵么?

在做一個租賃系統,有一張用戶信息表t_user,一張車輛信息表t_car,做車輛的租賃單想通過一個中間表來實現,但我想用訂單號(時間相關)來作為主鍵,這種情況下可不可以放棄使用聯合主鍵?而且順便請教一下,使用聯合主鍵的好處?

 

你這個例子不能用聯合主鍵,只能訂單號或者自增id作主鍵
因為這個"租賃單"表是核心的業務實體,在現實中的確會有一張紙制的租賃單據,它不是因為車輛和用戶才存在的。
以后如果業務擴展,比如新增了業務員表、分店表要和租賃單表關聯,你之前設計的聯合主鍵就失敗了。

 

 

補充:

1.  一張表可以沒有主鍵;

2.  一張表可以有多個主鍵(聯合主鍵);(通常在多對多關系中使用,寫在多對多的中間表中,注意其中的奧妙)

 

 

比如說一個學生管理系統,一個學生可以選多門課,一門可以有多個學生來選,學生表學號stu_id是主鍵,課程表cou_id是主鍵,多對多關系要用中間表---“學生選課表”enrol來實現數據的關聯,enrolyou兩種設計方式,第一種是:
CREATE TABLE enrol (
  cou_id int ,
  stu_id int ,
  accept varchar(32) ,
  score varchar(32) ,

  CONSTRAINT enrol_ibfk_1 FOREIGN KEY (cou_id) REFERENCES course (cou_id),
  CONSTRAINT enrol_ibfk_2 FOREIGN KEY (stu_id) REFERENCES student (stu_id),
  primary key(class_id,stu_id)
);
就是采用復合主鍵,第二種是:
CREATE TABLE enrol (
  enrol_id int primary key,
  cou_id int ,
  stu_id int ,
  accept varchar(32) ,
  score varchar(32) ,

  CONSTRAINT enrol_ibfk_1 FOREIGN KEY (cou_id) REFERENCES course (cou_id),
  CONSTRAINT enrol_ibfk_2 FOREIGN KEY (stu_id) REFERENCES student (stu_id)
);
采用了一個單獨的主鍵,stu_id和cou_id知識普通的字段。
這兩種方式哪個好?為什么?

現在都不建議使用復合主鍵了嗎,但是不使用復合主鍵的話,沒法保證學生不會重復選課。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM