資料庫設計之EAV(實體、屬性、值),eav實體
有這麼一個業務,用於客戶記錄每天做的事情,由於是非常專業的事情,需要專業的記錄本,這種記錄本有20多種。實際工作中也是有20多樣的記錄本,記錄本的格式每隔一年會有點變動。如何進行資料庫設計?
有兩種方案:
1.為每個記錄本建單獨的表。
2.動態表,把記錄本的屬性放入到字典中,記錄本的內容以實體、屬性、值的形式儲存。
--儲存記錄本的格式
createtable note_dictionary
(
dictionary_idnumber,
dictionary_typevarchar2(50),--記錄本的類型,就是那20多種記錄本
dictionary_namevarchar2(200)--記錄本中的名稱
);
--儲存記錄本的內容
createtable note_content
(
content_idnumber,
note_id number,--具體的一個記錄本的id
dictionary_idnumber,--記錄本中欄位的id
contentvarchar2(1000)--欄位的內容
);
如果只是從開發人員的角度來看,會選擇方案2。方案1工作量多大啊,每次改記錄本的格式都要做調整,方案2都有擴充型啊,調整格式都不需要改代碼,區區2張表解決了20多張表的問題,多酷。毫無爭議的選擇方案2。
選擇方案2後,會犧牲很多傳統資料庫設計代碼的好處,如果記錄本之前是有關係的,實現會變得更複雜。
1.記錄本中的欄位類型無法制定,如果是Date和number,只能用varchar2表示。關於類型選擇不正確會造成什麼問題,在我之前的blog中有寫到。再者統計也可能出現問題,即使你前段控制的再好,也不能保證最後到資料庫中後的是正確的,這個問題看到的太多了。
2.不能加not null的約束和預設值。
3.如果要查某個記錄本的a欄位,需要先去找字典,然後再到內容表中去找,不直觀,涉及到後期維護資料較麻煩。
4.如果記錄本之間是有關係,要建立關聯關係,需要再加表,實現很複雜。
5.在一段時間後內容表會變得非常之笨重,系統中就屬它資料量大。
6.我以前維護過這種設計代碼,因為是通用的,有時候改了這裡,也不知道會不會影響其他的地方。Java代碼中使用了反射,debug很難調試,問題難定位。總體來說,有一種身不如死的感覺。
7.所有複雜一點的查詢都會變得複雜。
上面的模組我傾向選擇方案1,開發工作量大一點,但維護工作量小,資料更加精準。那是不是一定不要用方案2呢?也不是,業務,業務,還是業務,如果你的單據不需要統計分析,資料量也不大,單據種類非常多,開發人員水平很高,你想要做到記錄本可配置,那可以選擇方案2。如果你不詳細瞭解業務的情況下,堅持選擇方案2,你必須承擔我上述說的風險。
資料庫設計中實體與屬性以及關係的確定
什麼意思,學生是一個實體,課程是一個實體;學生的學號是屬性,課程的名稱是屬性;學生的選課記錄是關係。你應該不是問的這個吧。
資料庫 名詞解釋:單值屬性與多值屬性
簡單的說:單值屬性就是只能是一個值
多值屬性可以有一個或者兩個以上的值
舉個考試的例子:
設有員工實體Employee (employeeID, name, sex, age, tel, departID),其中employeeID為員工號,name為員工姓名,sex為員工性別,age為員工年齡,tel為員工電話,記錄該員工的手機號碼、辦公室電話
(1) A.name,可以用employeelD可以區別
B.sex,可以不作任何處理
C.tel,可以將tel加上employeeID獨立為一個實體
D.tel,可以強制只記錄一個電話號碼
tel 為多值屬性,因為它可以是手機號碼,也可以是辦公室電話!!
屬性:
屬性和分類單獨進行定義。每一個屬性僅僅定義一次,但是可以在多個分類中使用。例如,“Description”(描述)屬性可以使用在多個分類中,但是只需在架構中定義一次即可,以保持資料的一致性。
屬性用來描述對象。每一個屬性都擁有它自己的定義,定義則描述了特定於該屬性的資訊類型。架構中的每一個屬性都可以在“Attribute-Schema”分類中指定,該分類決定了每一個屬性定義所必須包含的資訊。
能夠應用到某個特殊對象上的屬性列表由分類(對象是該分類的一個執行個體)以及對象分類的任何超類所決定。屬性僅僅定義一次,但是可以多次使用。這確保了共用同一個屬性的所有分類能夠保持一致性。
多值屬性
屬性可以是單值的也可以是多值的。屬性的架構定義指定了屬性的執行個體是否必須是多值的。單值屬性的執行個體可以為空白,也可以包含一個單值。多值屬性的執行個體可以為空白,也可以包含一個單值或多值。多值屬性的每一個值都必須是唯一的。
索引屬性
索引應用於屬性,而不是分類。對屬性進行索引有助於更快地查詢到擁有該屬性的對象。當您將一個屬性標記為“已索引”之後,該屬性的所有執行個體都會被添加到該索引,而不是僅僅將作為某個特定分類成員的執行個體添加到索引。
添加經過索引的屬性會影響Active Directory的複製時間、可用記憶體以及資料庫大小。因為資料庫變得更大了,所以需要花費更多的時間進行複製。
多值屬性也可以被索引。同單值屬性的索引相比,多值屬性的索引進一步增加了Active Directory的大小,並且需要更多的時間來建立對象。在選擇需要進行索引的屬性時,請確信所選擇的共用屬性,而且能夠在開銷和效能之間取得平衡。
一個經過索引的架構屬性還可以被用來儲存屬性的容器所搜尋,從而避免了對整個Active Directory資料庫進行搜尋。這樣不僅縮短了搜尋所需花費的時間,而且減少了在搜尋期間需要使用的資源數量。