2016-07-15 31 views
0

我有一個使用2個外鍵字段和一個日期字段的表。 有一個表使用3個或更多字段作爲主鍵常見嗎?這樣做有什麼不利嗎?我可以在一張桌子上的組合主鍵中有太多的列

-

我的3張表是員工,培訓和emp_training。 employees表持有員工數據。培訓表包含不同的培訓課程。我正在將emp_training表設計爲EmployeeID(FK),TrainingID(FK),OnDate字段。

員工可以做多個培訓課程,並且可以多次進行相同的培訓課程。但他們不能在同一天多次參加相同的培訓課程。 哪個是更好的實現:

選項A - 讓所有3場主鍵

選項B - 添加一個自動編號PK場,並使用查詢發現任何潛在的重複。

我已經創建了許多表使用2個字段作爲主鍵之前,但從來沒有3,所以我很好奇,如果有任何缺點與選項訴訟中提出的

+0

在那裏,我修改了你的標題。我想這就是你想說的。 – Drew

+0

還有一點(除了下面的答案):你的*但他們不能在同一天超過一次同一訓練課程*是一個反對PK的**理由**:這不是絕對的規則,只是一種商業邏輯。如果出現這種情況,你會怎麼做?每天兩次可以進行同一個課程?那你會怎麼做? – Shnugo

回答

1

我不認爲這有什麼問題創建一個帶有組成PK的表格,這些表格在更大的數據庫中是必需的。在用OnDate字段形成PK的2FK創建表格時沒有真正的問題。這兩種方式都是可行的。 祝你好運!

+0

更重要的是那麼問題*可能一個PK由多個列組成* *是問題*這個索引是否聚集在一起並且是參與列被隱式排序?*。一個不好的聚集索引也會減慢所有其他索引,因爲它作爲它們的查找鍵... – Shnugo

2

是的,你可以有一個糟糕的策略選擇太多的列爲複合主鍵(PK),如果更好的策略可以聘請通過二級索引的唯一性。

請記住,PK是特殊的。數據只有1個物理/集羣排序。通過插入和更新(以及現任洗牌)對數據所做的更改在那裏有開銷,如果保留在二級索引中則不會存在。

所以下面可以具有不那麼無顯着差異:

  1. 用5個組合柱

  • 主鍵具有1或2列的主鍵加上
    • 二級索引如果您使用的是獨特性通過精心
  • 數據頁之間的數據保持羣集索引(PK)的前任務運動HT。這可能暗示爲什麼經常看到:

    (
    id int auto_increment primary key, 
    ... 
    ) 
    

    表中的設計。

    用性能指數寬度:

    在1的PK的寬度。以上是狹窄的。 2.的寬度可以相當寬。傳播到子關係的更廣泛的鍵會降低性能和併發性。 FK組合物的

    例:

    外鍵的組合物的特殊情況,根本無法在不使用一個單一的列索引,優選PK,如圖這個最近礦Answer來實現。

    1

    如果您在多個列上分配主鍵,它將是複合主鍵。例如,

    CREATE TABLE employee(
        training VARCHAR(10), 
        emp_training VARCHAR (20), 
        OnDate INTEGER, 
        PRIMARY KEY (training, emp_training, OnDate) 
    ) 
    

    在訓練中,emp_training,OnDate會有唯一的記錄,並且不能一起爲零。

    如前所述,您可以有一個由多列組成的主鍵。

    如果問題是如何分開製作主鍵,那是不可能的。但是,您可以創建1個主鍵並添加兩個唯一鍵

    +0

    你應該從不**創建沒有名字的PK(或任何其他約束)!使用'CONSTRAINT PK_employee PRIMARY KEY(training,emp_training,OnDate)'。 – Shnugo

    +0

    感謝您的幫助提示。你是對的。 –

    1

    值得一提的是,與SQL Server的默認PK是的唯一集羣鍵,但您可以創建非集羣PK也是。

    您可以定義一個新的聚簇索引,它不是PK。 「主鍵」實際上只是一個名字...

    最重要的問題是:哪些列參與聚簇鍵和(這是最重要的問題):它們是否具有隱式排序?並且(非常重要)):是否有很多更新操作會更改參與列的內容?

    您必須知道,羣集密鑰定義了硬盤上的物理順序。換句話說:集羣密鑰是表本身。您可以考慮包含所有列的索引。如果您的領先專欄(最壞的情況是)是GUID,則每個插入到您的表的都不會按順序。這導致99.99%的碎片。

    如果聚簇索引綁定到插入時間或運行數(最佳情況),它將永遠不會進入碎片!什麼讓事情變得更糟:如果有聚集鍵(不管它是否稱爲PK),它將用作其他索引的查找鍵。

    因此:在許多情況下,最好使用運行編號作爲聚簇鍵和非聚簇多列索引,重建速度要快於聚簇索引。

    所有指標都將從中受益!

    我對你的提醒:

    • 選項C:運行號爲PK和另外一個獨特的多列項,以確保數據的完整性。這裏不需要使用自己的邏輯...
    相關問題