2014-03-13 56 views
3

我已經實現存儲拓撲關係通過以下方式:聯結表的必要性是什麼?

1.A一般結關係表:

表:關係

列:ID PARENT_TYPE PARENT_ID parent_prop CHILD_TYPE child_id child_prop

哪些連接通常不能被大多數sql引擎執行。

2.Relation特定結表

表:Class2Student

色譜柱:ID PARENT_ID parent_prop child_id child_prop

在它連接能夠防止被執行。

3.在兩個雙向對象的text字段中存儲相關對象的相關對象的列表/字符串映射。

等級:Class

類屬性:ID名稱學生

表列:ID名稱students_keys

行數:1的 「歷史」[{類型:Basic_student,ID:1}, {type:Advanced_student,id:3}]

要啓用sql引擎的連接,可以編寫一個自定義模塊,這個模塊會變得更容易如果students_keys的內容只是[1,3],即與顯式的Student類型有關係。

我看不到結表的一點是什麼:

的問題是在上下文以下。比如,我看不出任何問題的結表要求以下參數來緩解,實際上存在:

  • 無力邏輯上正確保存一個雙向的關係(如 有雙向關係或沒有數據成爲孤兒任何 與keys場的關係,因爲一個遞歸地保存並可以執行其它操作 (刪除,更新)很容易)
  • 無力加入有效

我不徵求意見根據您對最佳實踐的個人意見或任何關於正常化的邪教言論。

的明確的問題(S)如下:

  1. 什麼是其中一個將要查詢未通過查詢所屬對象的keys領域提供了一個結臺的實例?
  2. 什麼是sql引擎提供的計算上下文中的邏輯實現問題?
  3. 與問候到junction table Vs的keys領域唯一實現差異如下:

當下列性質的查詢你需要匹配對keys場或者是自定義索引執行搜索或其他合理的實施方式:

class_dao.search({students:advanced_student_3,name:「history」});

搜索具有特定的學生,名爲「歷史」

與之相對搜索結表的索引列,然後選擇選擇恰當的類類。

我一直無法確定答案,爲什麼一個聯結表在邏輯上是完全由字面意義上的任何理由。 我並不是說這是事實,或者我是否有這種或那種宗教偏好,這可以通過我實現多種方式來實現。我的問題是我不知道他們是什麼。

+0

所以,你想存儲非規範化的數據在關係數據庫? – Jodrell

+0

我想了解計算成本環境中聯結表的功能點,而不一定是含糊不清的術語「關係數據庫」。我不想重申我想了解這一點的整個背景,因爲那只是重申了這個問題。 – MetaChrome

+0

TL; DR--你如何在數據庫中存儲N-N關係,特別是當關系雙方有數百條記錄時? – Arvo

回答

2

我看到它的方式,你必須有幾個實體

CREATE TABLE StudentType 
(
    Id Int PRIMARY KEY, 
    Name NVarChar(50) 
); 

INSERT StudentType VALUES 
(
    (1, 'Basic'), 
    (2, 'Advanced'), 
    (3, 'SomeOtherCategory') 
); 

CREATE TABLE Student 
(
    Id Int PRIMARY KEY, 
    Name NVarChar(200), 
    OtherAttributeCommonToAllStudents Int, 
    Type Int, 
    CONSTRAINT FK_Student_StudentType 
     FOREIGN KEY (Type) REFERENCES StudentType(Id) 
) 

CREATE TABLE StudentAdvanced 
(
    Id Int PRIMARY KEY, 
    AdvancedOnlyAttribute Int, 
    CONSTRIANT FK_StudentAdvanced_Student 
     FOREIGN KEY (Id) REFERENCES Student(Id) 
) 

CREATE TABLE StudentSomeOtherCategory 
(
    Id Int PRIMARY KEY, 
    SomeOtherCategoryOnlyAttribute Int, 
    CONSTRIANT FK_StudentSomeOtherCategory_Student 
     FOREIGN KEY (Id) REFERENCES Student(Id) 
) 
  1. 通用於所有的學生對Student表列的任何屬性。
  2. 具有額外屬性的學生類型被添加到StudentType表中。
  3. 每個額外的學生類型都會得到一個Student<TypeName>表來存儲其特定屬性。這些表格與Student有可選的一對一關係。

我認爲你的「稻草人」聯結表是EAV反模式的一個部分實現,唯一一個這是明智的,當你不知道你需要建模什麼屬性時,即你的數據將完全沒有結構化。當這是一個真正的需求時,關係數據庫開始看起來不太理想。在這些場合,請考慮使用NOSQL/Document數據庫替代方案。


接點表在以下情況下將會很有用。假設我們向模型中添加一個Class實體。

CREATE TABLE Class 
(
    Id Int PRIMARY KEY, 
    ... 
) 

它的concievable,我們想存儲學生和班級之間的多對多realtionship。

CREATE TABLE Registration 
(
    Id Int PRIMARY KEY, 
    StudentId Int, 
    ClassId Int, 
    CONSTRAINT FK_Registration_Student 
     FOREIGN KEY (StudentId) REFERENCES Student(Id), 
    CONSTRAINT FK_Registration_Class 
     FOREIGN KEY (ClassId) REFERENCES Class(Id) 
) 

這個實體可能是存儲與學生的註冊相關的屬性的正確地方,例如可能是完成標誌。其他數據自然會與這個交匯點相關,也可能是特定類別的出勤記錄或成績歷史記錄。

如果您不以這種方式與ClassStudent相關聯,您將如何選擇兩個,一個班級的所有學生以及一個學生閱讀的所有班級。性能方面,這可以通過關鍵列上的索引輕鬆優化。


當多對多的realtionships存在沒有任何屬性我同意在邏輯上,結表不需要存在。然而,在關係數據庫中,結表仍然是一個有用的物理implmentaion,也許是這樣的,

CREATE TABLE StudentClass 
(
    StudentId Int, 
    ClassId Int, 
    CONSTRAINT PK_StudentClass PRIMARY KEY (ClassId, StudentId), 
    CONSTRAINT FK_Registration_Student 
     FOREIGN KEY (StudentId) REFERENCES Student(Id), 
    CONSTRAINT FK_Registration_Class 
     FOREIGN KEY (ClassId) REFERENCES Class(Id) 
) 

這讓像

// students in a class? 
SELECT StudentId 
FROM StudentClass 
WHERE ClassId = @classId 

// classes read by a student? 
SELECT ClassId 
FROM StudentClass 
WHERE StudentId = @studentId 

additionaly簡單的查詢,這使得一個簡單的方法來管理的關係部分或全部來自任何方面,這將與關係數據庫開發人員熟悉,並且可以被查詢優化人員使用。

+0

這個問題不是處理學生的層次類型,而是處理Class2Student關係。以最簡單的情況來評估聯結表的功效,學生類型層次結構的添加是爲了說明實現#3所需的自定義索引的類型。在聯結表提供的[計算性能,功能]方面有什麼優勢?如果它強制2個連接vs 1並且不提供任何功能,爲什麼要使用聯結表? – MetaChrome

+0

@MetaChrome我希望我的擴展答案能更好地回答你的問題。 – Jodrell

+0

關係本身的屬性示例是有效的,並且需要結點/關係實體。 – MetaChrome