1

我正在設計一個模式,其中一個案例可以附加多個表單並且表單可以用於很多情況。 Form表基本上保存了在客戶端呈現的html表單的結構。提交表單時,字段的名稱/值對將分開存儲。如何保持名稱/值屬性與連接表分離如下有什麼價值?數據庫模式 - 多對多規範化

CREATE TABLE Case (
    ID int NOT NULL PRIMARY KEY, 
    ... 
); 

CREATE TABLE CaseForm (
    CaseID int NOT NULL FOREIGN KEY REFERENCES Case (ID), 
    FormID int NOT NULL FOREIGN KEY REFERENCES Form (ID), 
    CONSTRAINT PK_CaseForm PRIMARY KEY (CaseID, FormID) 
); 

CREATE TABLE CaseFormAttribute (
    ID int NOT NULL PRIMARY KEY, 
    CaseID int NOT NULL FOREIGN KEY REFERENCES CaseForm (CaseID), 
    FormID int NOT NULL FOREIGN KEY REFERENCES CaseForm (FormID), 
    Name varchar(255) NOT NULL, 
    Value varchar(max) 
); 

CREATE TABLE Form (
    ID int NOT NULL PRIMARY KEY, 
    FieldsJson varchar (max) NOT NULL 
); 

我是我過分複雜的架構,因爲同樣的多對多的關係可以通過轉動CaseFormAttribute表到連接表和獲得完全擺脫CaseForm表如下的實現?

CREATE TABLE CaseFormAttribute (
    ID int NOT NULL PRIMARY KEY, 
    CaseID int NOT NULL FOREIGN KEY REFERENCES Case (ID), 
    FormID int NOT NULL FOREIGN KEY REFERENCES Form (ID), 
    Name varchar(255) NOT NULL, 
    Value varchar(max) NULL 
); 

基本上我想問的是哪個更好的設計?

+0

他們都會工作,但它取決於你需要什麼表。你的ERD是什麼樣的? –

+0

有沒有比另一個更好的價值? – adam78

+0

這取決於你是否需要caseform表或不,但我不能評論,因爲我不知道你的數據庫設計或要求 –

回答

0

拆分兩者的主要好處取決於是否將其他字段添加到CaseForm表中。例如,假設你想記錄表單是否不完整。您可以添加一個未完成位字段。現在,你有獲取信息的主要選項:

  1. 聚集在CaseForm索引掃描
  2. 創建於CaseForm.Incomplete非聚集索引,其中包括CaseID,FormID,並掃描該

如果你沒拆表,您的兩個主要選項是:

上CaseFormAttribute
  • 酶Cre
  • 聚集索引掃描在包含CaseID,FormID和掃描的CaseFormAttribute.Incomplete上查找非聚集索引
  • 對於本示例而言,查詢選項1和2在性能方面大致相同。引入非聚集索引會以多種方式增加開銷。它比聚集索引稍少一點(可能需要在此特定示例中掃描更多的讀取),它是CaseForm將佔用的額外存儲空間,並且必須維護索引以更新表格。選項4也將執行類似的操作,但與選項2的警告相同。選項3將是您表現最差的執行者,因爲聚簇索引掃描將包括讀取「值」字段中的所有BLOB數據,即使它只需要「未完成」中的位以確定是否返回該(Case,Form)對。

    所以它確實取決於你將來朝着什麼方向發展。另外,如果您使用拆分方法,請考慮將CaseFormAttribute.ID轉換爲CaseForm,然後在CaseFormAttribute中將CaseForm.ID用作PK/FK。這裏需要注意的是,我們假設所有的表單將被同時插入給定的案例。如果這不是真的,那麼你會邀請一些頁面拆分,因爲你的插入會有點隨機,但仍然會增加。

    +0

    要求是一種情況下可以有多個附加形式但不是相同的形式。它需要是多對多的關係。那麼我需要使用三列(CaseId,FormId,Name)來創建複合鍵嗎? – adam78

    +0

    @ adam78我現在看到它 - 謝謝指出。我相應地編輯了我的答案。你的密鑰是正確的,你不應該在密鑰中包含名稱。 – mathewb

    +0

    不,我認爲你是對的 - 在我的解決方案2我最終會有重複的表單,所以我需要在該實例中添加一個唯一的鍵(CaseId,FormId,Name)。 – adam78