資料庫設計方法論 – 繼承
- 2019 年 10 月 12 日
- 筆記
繼承這個概念做java開發的同學應該都很熟悉了,繼承指的是子類繼承父類的特徵和行為,使得子類對象(實例)具有父類的實例域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為。
資料庫設計的時候也是有繼承關係的,在資料庫設計方法論中繼承有三種,分別是具體表繼承(Concrete Table Inheritance)、單表繼承(Single Table Inheritance)、類表繼承(Class Table Inheritance)。我們實際設計中經常會不經意中使用到資料庫到繼承,下面分別介紹一下他們的概念:
概念解析
-
具體表繼承
不建立父對象,將父對象的所有屬性轉移到子對象中,為每個子對象建立對於的表。 -
單表繼承
在一個寬表中列出所有父對象和子對象的屬性,同時用一個標識列表示該行數據存儲的是哪個子類的數據。 -
類表繼承
對父對象和每個子對象建立一個對應的表,然後在子表中設置該子表的主鍵為與父表關聯的外鍵。
設計示例
假如你現在在做個教學系統,系統中有三個角色:學生、家長、老師。
學生的屬性:姓名、年齡、性別、身份證、入學時間、學號、學分
家長的屬性:姓名、年齡、性別、職業、學歷
老師的屬性:姓名、年齡、性別、教齡、學科、是否已婚
不同繼承方案的實現如下:
- 具體表繼承(三張獨立表)
- 學生表(ID、姓名、年齡、性別、身份證、入學時間、學號、學分)
- 家長表(ID、姓名、年齡、性別、職業、學歷)
- 老師表(ID、姓名、年齡、性別、教齡、學科、是否已婚)
- 單表繼承(一張大寬表+類型欄位用以區分)
- 用戶表(ID、姓名、年齡、性別、身份證、入學時間、學號、學分、職業、學歷、教齡、學科、是否已婚、類型)
- 類表繼承(四張表:一張父表表+三張子表)
- 用戶表(ID、姓名、年齡、性別)
- 學生表(ID、用戶ID、身份證、入學時間、學號、學分)
- 家長表(ID、用戶ID、職業、學歷)
- 老師表(ID、用戶ID、教齡、學科、是否已婚)
方案對比
-
具體表繼承
優點:獲取完整對象不需要聯表查詢;表中沒有無關屬性(跟單表繼承的對比)
缺點:添加公共屬性時需要修改多個表;查詢公共欄位展示需要查詢多個表並作
union
操作(如:頁面需要展示所有的用戶,顯示用戶的公共欄位)使用場景:適用於子表關聯性較弱的業務場景,並且識別出系統沒有公共數據查詢的需求
-
單表繼承
優點:庫表設計簡單,獲取子表數據時不需要join連接。
缺點:表空間利用率低,子表出現無關屬性;擴展子表屬性時需要修改數據表(鎖表)。
使用場景: 適用於子類屬性較少的情況。比如可預見的時間內子類的屬性都比較少時可以使用這種方式,畢竟查詢簡單,不需要聯表查詢。
-
類表繼承
優點:庫表的層次結構清晰;為子類添加屬性不用修改父表,添加公共屬性不需要修改子表;查詢公共數據時不需要去查詢多個表;擴展性強
缺點:獲取對象完整數據需要join查詢,在數據量很大時影響查詢效率
使用場景:適用關聯性較強的業務場景,子表屬性變化較大。
總結
資料庫設計的原則就是沒有原則,需要根據業務場景選擇具體的設計方法
今天說的資料庫繼承方案或者資料庫範式都是這樣,並不是說你資料庫設計的擴展性強或者完全遵循4NF範式消除一切數據一致性問題就最好,設計帶來的join查詢效率也需要慎重考慮。
歡迎關注我的個人公眾號:JAVA日知錄