2016-10-08 100 views
1

我試圖設計一個數據庫,和我的一個表是這樣的:我可以在這個外鍵中避免「冗餘」嗎?

player_in_tournament

ID_tourn | ID_player | and other attributes... 

和PK由兩個第一列。

在表tournament_game(表示比賽的比賽/比賽)中,我想引用player_in_tournament中的2個「對象」,所以我應該有兩個外鍵,每個都由ID_player和ID_tour。

但是ID_tour在兩個「對象」中都是相同的。

問題是改變第一個表的PK並添加ID_player_in_tournament是一個好主意,並在tournament_game表中使用它作爲外鍵。

+0

請編輯您的問題並提供樣本數據,以便我們可以看到您想表示的內容。 –

回答

1

將代理鍵添加到player_in_tournament表使得構建代表具有兩個不同ID_tourn的玩家的tournament_game成爲可能。這樣做可以避免冗餘,但會導致不一致。

你應該有參與兩個外鍵三個字段 -

  • (ID_tourn, ID_player1)第一個player_in_tournament
  • (ID_tourn, ID_player2)第二player_in_tournament

注意的是,同一列ID_tourn參與了兩個外鍵關係:

create table player_in_tournament(
    ID_tourn int 
, ID_player int 
, ... 
, primary key(ID_tourn, ID_player) 
); 
create table tournament_game(
    ID_tourn int 
, ID_player1 int 
, ID_player2 int 
, ... 
, foreign key (ID_tourn, ID_player1) 
     references player_in_tournament(ID_tourn, ID_player) 
, foreign key (ID_tourn, ID_player2) 
     references player_in_tournament(ID_tourn, ID_player) 
); 
+1

這是真的!我沒有想過這個不一致的問題......並且我也不知道tournament_game的ID_tourn列可以這種方式使用(參與兩個外鍵)。非常感謝!! :-) – p0kero

0

正如您正確猜測,這將使tournament_game表中的外鍵只有兩列而不是四列,這將提高您需要在SQL語句中編寫的聯接的便利性和可讀性。唯一的缺點是表格寬度的增加,但是每行只有幾個字節。你可能知道,這被稱爲「代理鍵」(而不是「自然鍵」)。 如果這樣做,請確保在「自然鍵」(ID_tourn, ID_player)上保留唯一鍵或約束,以確保這兩個字段保持唯一性,並保留數據一致性。

0

這裏有2個表格table player_in_tournament和tournament_game。顧名思義,tournament_game是關於比賽的表格,所以它應該有比賽ID和比賽名稱以及與比賽相關的所有其他屬性。另一個表player_in_tournament應該有玩家ID,玩家名稱和錦標賽ID(來自tournament_game表的引用)以及與玩家相關的其他屬性。這應該根據您的查詢進行設計。

1

首先你有一個比賽。你給它一個你稱之爲ID_tourn的人造標識符。這可能是因爲它沒有真正的名字或數字,比如錦標賽2016Q3。 (如果是的話,你可以使用這個比賽號碼,而不必人爲地添加一個ID。)

然後你有球員。這裏再次創建一個ID。可能是因爲他們是沒有任何自然識別號碼的現實生活中的球員。(如果他們只是你遊戲中的玩家,他們會有登錄名或用戶名,你可以用它來代替。)

現在你有一個聯賽的球員。記錄自然是由錦標賽標識符和玩家標識符來標識的。

最後你有一個比賽遊戲,顯然是兩個比賽球員的比賽。所以一個記錄將包含比賽標識符和兩個球員標識符。它將包含兩個外鍵:ID_tourn + ID_player1和ID_tourn + ID_player2。

所有這些,使用組合鍵和自然鍵(如可能的話,登錄名稱)是創建數據庫的一個概念。另外一個是表由這些人工ID和鏈接表。我曾在大型數據庫上工作過,並且更喜歡第一個概念,但也有其他人更喜歡全ID概念。

下面是兩個比較的例子。 PK =主鍵,FKN =外鍵,PK2 =唯一約束(如第二PK)

自然鍵/組合鍵

  • 表的客戶端(客戶)=> PK(客戶)
  • 表項(ITEM_NUMBER,說明,價格)=> PK(ITEM_NUMBER)
  • 表順序(ORDER_NUMBER,order_date的,客戶編號)=> PK(ORDER_NUMBER); FK1(client.client_number)
  • table order_item(order_number,item_number,amount)=> PK(order_number,item_number); FK1(order.order_number); FK2(item.item_number)

Artikficial標識

  • 表客戶機(id_client,客戶編號)=> PK(id_client); PK2(client_number)
  • 表項目(id_item,item_number,description,price)=> PK(id_item); PK2(item_number)
  • 表格順序(id_order,order_number,order_date,client_number)=> PK(id_order); PK2(order_number),FK1(client.client_number)
  • table order_item(id_order_item,order_number,item_number,amount)=> PK(id_order_item); PK2(ORDER_NUMBER,ITEM_NUMBER); FK1(order.order_number); FK2(item.item_number)
+0

謝謝!這對我來說是一個非常有用的信息 – p0kero