連結到許多其他表的表(但每條記錄在任何時候只有一個)
我正在重新設計驅動我們公司電話系統的應用程序。
電話應用程序中有各種類型的功能,例如菜單系統、公告、基於時間的呼叫路由等。
這些目前都儲存在一個名為“特徵”的表中,其中有一個描述特徵類型的列舉。但是,這意味著該表中的所有欄位都有通用名稱,例如“Setting1”、“Setting2”等。此外,表中的每個“特徵”記錄都連結到另一個名為“TargetFeature”的“特徵”記錄,所以表明電話系統在完成目前記錄的動作後知道該做什麼。當涉及到菜單系統時,這可能會變得複雜,因為可能有多達 11 個不同的 TargetFeatures、選項 0 到 9 和 STAR。
通過重新設計,我想將這些功能分離到它們自己的表格中。IE。菜單表、基於時間的呼叫路由表等。
我不知道如何最好地建立這種關係。每個要素表都可以連結到任何其他類型的要素表。
如果有 10 個不同的特徵表,則每個特徵表都需要一個可為空的 ID 來引用所有可能是 TargetFeature 的表。
但是,對於菜單系統,由於有 11 個選項可供選擇,因此需要一個具有 11 個選項 x 10 個特徵表 ID 的表,其中 90% 的欄位為空。
誰能推荐一個合適的結構,允許多個表與多個其他錶鍊接,而不必為每個可能的其他表創建 ID 欄位?
我正在考慮使用帶有 guid 的連結表,但無法弄清楚。
非常感謝!
解決方案
感謝 David Spillett 給了我所需的理解。
我創建了一個“ParentFeatures”表,然後為每種功能類型創建了子表。
所有子表都有一個 ParentFeaturesId 欄位,因此它們可以與包含通用欄位(例如 Name 和 UserId)的 ParentFeatures 表相關聯。
最後,所有子表都具有所需數量的 TargetParentFeatureId 欄位,具體取決於每種類型的功能需要多少個目標才能執行。
因此,所有功能現在都可以通過使用其 TargetParentFeatureId 欄位來指向 TargetFeature。
使用 Pomelo.EntityFrameworkCore.MySql 庫 v5.0.1 使用 EF Core 5.0 和 MySQL 8.0.19,我已經成功地測試了這個方法,它似乎工作得很好。
再次感謝。
處理具有相同關係的不同類型
為了打破具有共同關係(可能還有其他屬性)但實體特定屬性的實體,請查看表繼承。一些 DB 具有內置支持,可以在此模式下提供一些幫助,但這是您可以在任何地方實現的常見模式:
ThingsTable SubThing1 =========== ================== ThingID (PK) <----- ThingID (FK) ThingType | SubThing1ID (PK) ThingName | SubThing1Property1 OtherCommonProperty | SubThing1Property2 LinkToSomethingElse (FK) | | SubThing2 | ================== `-- ThingID (FK) SubThing2ID (PK) SubThing2Property1 SubThing2Property2
顯然使用比 Thing 和 SubThing 更好的名稱!當然,每個 SubThing N Property N實際上應該是一個有意義的名稱,例如“ServiceDate”或“ThribbleLength”。有一個論點是每個子類型都沒有單獨的 SubThingID,因為主標識符在每個子表中都是唯一的,因此可以充當主鍵。
這樣,主“Things”表上只存在公共屬性,實體特定屬性在它們自己的表中出現,從而減少了大多數時間包含 NULL 的每個類型屬性的擴散。與其他實體的關係通常是主 Things 表上的常見屬性,但在其他地方可能存在特定於類型的關係,特別是如果一個或多個類型本身被建模為多表方式。
處理許多通常為 NULL 的屬性
表繼承處理通常為 NULL 的屬性,因為它們僅與許多可能的實體類型中的一種相關,因為僅與一種類型相關的屬性將僅存在於該子表中,但您可能仍然具有許多通常為 NULL 屬性的類型。這可能是可以的,但如果不是,您可以考慮查看“實體-屬性-值”(EAV)模型。請注意,EAV 通常被認為是一種反模式是有充分理由的,因此只有在它確實對您的需求最有效時才使用它。
更詳細的解釋
如果你搜尋“表繼承”和“EAV 模式”,你會發現很多關於這些建模方法的資訊,什麼時候合適,更重要的是什麼時候不合適。我不會嘗試用可以在其他地方找到的值得討論的書籍來填充這個答案!
更詳細?
這些是要研究的模型的一般建議。正如@bbaird 在他的評論中所建議的那樣,提供樣本數據可能會幫助人們針對您的情況提供更具體的建議。