2012-09-06 22 views
0

我正在和一位剛剛接觸編程的同事一起工作,我正在嘗試解釋一些ORM(和SRP)的概念,但我在某種程度上失敗了。這是一個Rails應用程序。數據建模 - 爲什麼不是一個扁平的屬性表?

我工作在一個應用程序的類層次結構是這樣的:

-CallFlow
- 路線(多態性)
--- RouteOptions

有特定屬性的各種路由和每個RouteType都有它自己的一組選項。理想情況下,對於我來說,會有一個call_flows表,每個路由類型都有一個表,然後是具有選項的路由類型,該路由類型有一個選項表。一個非常粗糙的小樣:

enter image description here

Simple_route和outbound_route沒有選擇。在有選擇的路線中,這是一個has_many關係,爲我們提供了該路線的一系列選項。

相反,我的同事希望將每個路由特定的所有字段放在call_flows表中。這是一個模式的樣機:

enter image description here

所以,你將有一個大的call_flows表,並不適用於每一個記錄字段。其實只有少數意志。我的背後我的造型決定的推理如下:

  • 它遵循了基本的標準化模式
  • 它減少了空值的數量,從而分貝大小
  • 它更靈活地應對變化
  • 它遵循基本的SRP原則

我是否缺少任何東西?如果有任何資源可以幫助新程序員實現數據庫規範化的重要性,那將是非常好的。

謝謝!

+1

你已經非常雄辯地解釋了它。如果你的同事不能接受你的解釋,爲什麼他會被外部資源所信服?這看起來像個人領導/自信問題。 –

回答

3

標準化背後的核心概念是Data Dependency vs Functional Dependency。在規範化的模式中,只有依賴關係是由業務或數據語義規定的功能依賴關係。例如,RouteOptions依賴於Route。

在非規範化表中,由於所有數據都存儲在所有地方,因此將存在數據依賴關係以及函數依賴關係。在這種情況下,執行交易非常困難,並且100%確信您的數據模型是一致的。

讓我們舉個例子吧。你想添加一個新的路由選項。這是你的交易。在標準化表中,您將在RouteOption表中創建一個新記錄,並將Route_ID填入同一記錄中。您完全確信您的數據模型在交易後是一致的。

取一個非規範化模式,假設你有相同的RoutOption表和一個RouteSummary表,其中有幾個表的列。在此架構上執行上述事務時,您的數據模型不一致。您必須「記住」更新RouteSummary表。幾天之後,將會創建一些其他表格,這些表格也將具有RouteOption。預先存在的交易將不知道這個新表。

還有一個非標準化模式的地方。就是說,當你的數據存儲不是事務性的。如果它是一個ReadOnly模式,主要用於分析原因,則不會有事務處理,因此不存在數據不一致的風險。因此,它們在該用例中是可以的。

1

我真的不明白你通過額外的* _options表獲得了什麼。即這裏發生的事情不能僅僅在表格中列出。這就是說,你用不同的路由類型,選項等描述的那種複雜的結構對我來說似乎是一種東西,它會使NoSQL更好地適應無模式存儲方法。在這種情況下,您可以擁有一個路線集合,每個路線集合可以具有關於屬性,選項等的獨特結構。

+0

對不起,我應該已經清楚 - 每條路線has_many選項表。所以這將是一系列的選擇。 –

1

您的情況看起來像設計模式的一個實例,稱爲「泛化專業化」或簡稱Gen-Spec。如何使用數據庫表建模gen-spec的問題始終在SO中出現。

如果您在OOPL(如Java)中對gen-spec進行建模,則可以使用子類繼承功能來爲您處理細節。您只需定義一個類來處理泛化對象,然後定義一個子類集合,並使用每個子類擴展其父類超類。這很簡單直接。

不幸的是,據我所知,關係數據模型沒有內置子類繼承,而SQL數據庫系統不提供任何這樣的設施。但你並沒有失敗。您可以設計您的表格以與OOP的類結構相似的方式對gen-spec進行建模。當新項目添加到廣義類時,您必須安排實現自己的繼承機制。詳情如下。

Martin Fowler標識模仿繼承的三種不同的表設計。您喜歡的設計接近福勒稱爲Class Table Inheritance的設計。您的同事所喜歡的設計與接近福勒稱爲Single Table Inheritance的設計相近。每種都有其優點和缺點。

類表繼承有趣的部分稱爲共享主鍵。在這裏,子類表有一個雙重職責的關鍵。它是主鍵,也是返回超類表的外鍵引用。在創建新條目時,應用程序必須將鍵值從超類表傳播到相應的子類表。

當你需要將數據連接在一起時,光滑的部分就會出現。基於共享主鍵的連接非常簡單,快速。

+0

我的同事想要做什麼叫做成分,其中STI和成分應該一起使用。只使用組合(調用流程有很多選項),你有一組多態關聯(ivr_route是一個call_flow,由選項組成)分解成一個巨型類。 –

相關問題