資料庫設計方法論 – 繼承

  • 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日知錄