2016-02-15 104 views
1

我真的不知道該如何標題。事情是我是一個一般的數據庫begginer,我想知道這是否是一個好習慣。MySQL - 升級主鍵?

所以我在我的DB類似這樣的人一些表:

create table AAA(
id_aaa int not null auto_increment, 
primary key (id_aaa) 
); 

create table BBB(
id_bbb int not null auto_increment, 
id_aaa_AAA int not null, 
primary key (id_bbb), 
foreign key (id_aaa_AAA) references AAA (id_aaa) 
); 

create table CCC(
id_ccc int not null auto_increment, 
id_aaa_AAA int not null, 
id_bbb_BBB int not null, 
primary key (id_ccc), 
foreign key (id_aaa_AAA) references AAA (id_aaa), 
foreign key (id_bbb_BBB) references BBB (id_bbb) 
); 

ERD:

AAA (1-n) BBB (1-n) CCC 

它是確定添加AAA的主鍵在CCC的「更快無障礙」因爲我可以通過BBB訪問?

+4

不,它不是。你冒着相互矛盾的價值風險。 –

回答

1

簡短的回答是:不要這樣做。您可能會冗餘地存儲可能會導致錯誤的數據 - 如果使用id_aaa_AAA = 1將CCC記錄指向帶有id_aaa_AAA = 2的BBB記錄,該怎麼辦?

長的答案是:有自然鍵和人工(技術)鍵...

你經常會有自然鍵識別的實體(如員工號,國際項目編號等)。這是一個公司,員工和銷售數據庫。大膽列是自然鍵,可以用來作爲主鍵的表:

  • 公司(ILN,COMPANY_NAME,...)

的ILN(國際位置編號)唯一標識一家公司。

  • 員工(ILN,employee_no,employee_name,...)

的員工在他們公司的員工數目。但它與公司結合在一起是唯一的。 (即#123在A公司的僱員是別人比員工#123其他的當然是B公司)。

  • 銷售(ILN,employee_no,一年,總計)

多少一名員工在一年內出售?記錄由ILN +員工編號標識以識別員工加上年份。

現在很多人更喜歡設計一個帶有技術ID的數據庫,因爲他們發現這個概念更加靈活,並且通常有一些實體根本沒有自然鍵(例如,地址只能通過其所有組件的總和來標識,所以你更願意創建一個人工ID來引用它在其他表中)。這裏是相同的數據庫技術的ID:

  • 公司(COMPANY_ID,ILN,COMPANY_NAME,...)
  • 員工(EMPLOYEE_ID,employee_no,employee_name,COMPANY_ID,...)
  • 銷售(sales_id,EMPLOYEE_ID,一年總)

這裏每個表都有一個獨特的技術ID,通常是主鍵。 (當然,你也可以在company(iln)employee(employee_no, company_id)sales(employee_id, year)仍然有一個唯一的約束。)沒有冗餘,所以ILN只存儲在表公司。如果你想在2015年獲得公司的銷售總額,那麼你必須相應地瀏覽所有的表格。

與上述的自然鍵你不會。你在所有表中都有ILN,它仍然不會是多餘的,因爲它是所有表的關鍵部分(即,如果你從員工或銷售中刪除ILN,你不會知道記錄涉及哪個員工至)。在這裏你只訪問銷售表,以獲得在2015年

我找到自然鍵更舒適的工作銷售公司的總和,但它需要一些時間來正確地設計這樣一個數據庫,並經常如上所述,你仍然必須發明鑰匙,至於地址。但是數據訪問通常更加直接,即使是深層次結構,技術ID無法提供數據一致性。

所以長的答案是:決定是否要使用自然鍵。

0

嘗試在您的數據庫中存儲儘可能少的數據(即正常化您的數據)。

擁有表CCC中的冗餘信息只會回來困擾你。如果更新BBB中的一行以引用AAA中的新值,那麼您將不得不更新CCC中引用BBB中的行的所有行。在這個簡單的例子中,並不是太大的一筆交易,但是一旦你超過5張桌子,這可能變得非常混亂,難以追蹤。

+0

感謝您的回答!我沒有足夠的聲望來支持:/。我會閱讀正常化。 –