引言
面向對象的三個特征: 封裝(encapsulation), 繼承(inheritance), 多態(polymorphic), 其中繼承是我們三個特征中最重要的應該就是繼承了.
我們在程序中可以很自然, 很方便的表達繼承的關系. 但是針對這樣的繼承關系, 我們如何設計數據庫呢?通常我們有三種方式:
1. 一個繼承樹映射到一個表(one inheritance tree mapping to one table)
這種方式是將擁有共同父類的所有的類都看做成一張表(包括父類), 然後所有的類的所有的屬性取並集, 組成數據表的所有列.
如上圖類的結構圖, Vehicle是父類, 擁有兩個屬性Engine和wheel, 而子類Truck有屬性Container, 子類Car有屬性Acoustics.
數據表被映射成
類屬性 數據表字段 Engine Engine Wheel Wheel Container Contianer Acoustics Acoustics優點: 結構簡單, 在數據表操作層可以很方便的實現針對這三個對象的數據庫的insert, update, delete.
缺點: 這樣的設計數據表, 會有大量的數據冗余.
2. 一個繼承路徑映射一個表(one inheritance path mapping to one table)
按照這種方式: 創建兩張表, 分別是Truck和Car.
Truck 數據表
類屬性 數據表字段 Engine Engine Wheel Wheel Container ContainerCar 數據表
類屬性 數據表字段 Engine Engine Wheel Wheel Acoustics Acoustics優點: 沒有數據冗余.
缺點: 當需要查詢Vehicle的時候, 就需要在Truck和Car兩個表裡面進行查詢. 當有越多類繼承Vehicle的時候, 查詢的效率就越低.
3. 一個類映射到一個表(one class mapping to one table)
按照這種方式: 創建三張表, 分別是Vehicle, Truck和Car.
Vechile 數據表
類屬性 數據表字段 ID(Primary Key) Engine Engine Wheel WheelTruck 數據表
類屬性 數據表字段 ID(Foreign Key) Container ContainerCar 數據表
類屬性 數據表字段 ID(Foreign Key) Acoustics Acoustics優點: 為每個類創建表, 子表和父表通過ID進行關聯, 數據冗余小.
缺點: 當繼承體系的非常復雜的時候, 一些sql語句會非常復雜, 效率也會非常低下.
其實在上面三種方式中, 我們使用最多的最常見的應該算是第三種, 但是有些情況下, 我們也需要考慮下其他數據表的創建方式.
畢竟模式是在一些特定的場合下, 才能充分體現它的價值. 我們在開發的過程中, 在類的設計方面願意花費很多人力物力, 但是數據庫的設計
我們似乎缺少些斟酌. 如果大家有建模上面有什麼心得和高招, 多多交流.