1. 程式人生 > >業務中繼承關係研究(資料庫)

業務中繼承關係研究(資料庫)

情景如下:一個學員有兩類員工,老師和後勤人員.員工有id和姓名,老師還額外有個授課學科,用OO來表達如下

class Staff{
    private String id;
    private String name;
}
class Teacher extends Staff{
    private String subject;
}

首先第一個問題是否要專門建一個後勤員工這個類.應該是很有必要的.從類的角度來看即使一個類擁有另一個內的所有方法也並不意味著相同方法類的內部實現會相同.如果把這個方法寫到父類則有些不妥.

那麼下一個問題是資料庫如何設計.一般有三類方案

方案一:為父類建一張表,提供子類所有的欄位然後再加上一個標識來表明是哪個子類.那麼這張表將有很多欄位並且可能很多欄位的值都是空的.有的時候可以明確知道join的是老師那麼也需要join員工這個大表,影響效能

方案二:為每個子類建立一張表.這樣不會有冗餘欄位但帶來的問題是查詢時會有union操作,也會影響效能,並且無法做外來鍵約束

方案三是上面兩種方案的綜合.建立N+1張表,為每個子類建立一張表,再為那些公共欄位建立一個表也就是父表.至於子類表是否需要冗餘儲存父類表的欄位則可以再分為方案3.1和方案3.2我的看法是根據查詢需要來,儘量不要出現父類表join子類表的情況.但這只是繼承關係只有一級的情況,萬一由來個班主任繼承Teacher,那就是(M(N+1)+1)張表了.幾乎所有類,不管是父類還是子類都需要有一張表.

對於postgresql由於原生的提供了inherit的概念,所以在上面第三個方案上只需要真子類的NM張表,而不需要父類M+1表.真實的儲存應該是和方案二類似,也就是查父類表的時候通過union子類來實現的,只是資料自動幫我們完成了這個檢視.這也意味著有這方面的效能損失.postgresql的inherit還支援多重繼承,這就解決了一些在java中要靠介面來解決的問題.

在前一個問題的後面還有一個緊密跟著的問題:對於一些欄位和父類一樣的子類是否需要專門建立一張表呢?如果從資料的角度來看我認為是沒必要的(但是類也許還是需要一個專門的類,畢竟類是處理寫操作的)