數據字典是一種通用的程序設計方法。可以認為,不論什么程序,都是為了處理一定的主體,這里的主體可能是人員、商品(超子)、網頁、接口、數據庫表、甚至需求分析等等。當主體有很多的屬性,每種屬性有很多的取值,而且屬性的數量和屬性取值的數量是不斷變化的,特別是當這些數量的變化很快時,就應該考慮引入數據字典的設計方法。
數據字典有兩種形式
一, 把主體的屬性代碼化放入獨立的表中,不是和主體放在一起,主體中只保留屬性的代碼。這里屬性的數量是不變的,而屬性取值的數量可以是變化的。
二, 用一個表來放結構相同的所有屬性信息,不同屬性的不同取值統一編碼,用“類型”來區別不同的屬性,主體中保留屬性代碼的列表。這樣主體所擁有的屬性數量就是可變的了。
第二種數據字典比第一種更抽象,層級更高,也更具一般性、通用性。
這兩種形式的歸納有些抽象,為說明這兩種數據字典和它們的各種優點,下面舉個簡單的例子來說明:
現在有個需求,要在程序中處理“職員”信息。這里的主體就是“職員”,開始時“職員”有“國籍”、“證件”和“學歷”等屬性。
比如,對於一個“職員信息”頁面上的“國籍”下拉列表,我們可以就用第一種的數據字典來存儲不同的國家。如果不采取這樣的方法,就需要手動的把所有可能的國家名稱敲到頁面上。這首先有個效率的問題,每個需要用到國籍的地方都要敲一次,要敲多久?還有,如果有一天,像南斯拉夫,突然國家換名了,是不是要所有涉及的頁面都要手動地改變呢?
又比如,如果有一天一個代碼的名稱需要換一個,是不是要到數據庫中把已經經存在的所有數據都更新一遍呢?如“證件”,現在叫“身份證”,有一天想改為叫“居民身份證”。原來如果沒有用數據字典,就意味着,要把“身份證”這幾個字存到《職員表》等信息表中:
《職員表》
姓名 證件 性別
張三 身份證 男
李四 身份證 女
....
這樣,改名后就要手動改數據庫。但如果使用了數據字典,《職員表》里面存的就是:
《職員表》
姓名 證件 性別
張三 001 男
李四 001 女
....
另外增加了《證件表》:
《證件表》
證件id 證件名
001 身份證
002 暫住證
...
《證件表》就是第一種數據字典。要改變證件名稱時,只要把其中的“身份證”改成“居民身份證”就好了,只需修改一次。而且,《職員表》不用做任何修改,頁面上如果用到“證件”,也不用做修改。
還有在程序中有時需要判斷業務邏輯時,用:“select * from 職員表 where證件= ***”,原來***是“身份證”,使用數據字典后,就是001。證件改名后,就不用手動到程序里去改,程序也就不用重新測試、發布等等。
但第一種數據字典也有局限性。
使用第一種數據字典后,程序中除“職員”類外,還就需要有一個“國籍”類、一個“證件”類和一個“學歷”類,對應的數據庫中也需要增加一張“國籍”表、一張“證件”表和一張“學歷”表。“職員”類則需要包含一個對“國籍”類的引用、一個對“證件”類的引用和一個對“學歷”類的引用,對應的數據庫中“職員”表中也需要三個外鍵分別指向“國籍”表、“證件”表和“學歷”表。這樣的設計在類似“國籍”和“學歷”這樣的屬性比較少時是可行的,但是隨着系統復雜性的增加,系統中會出現大量結構類似的信息表和信息類,數量一直會增加到一個不可接受的地步。這里的“職員”,已經有了國籍、證件和學歷三個屬性,但如果職員還要增加“職位”屬性,那么必然要多出個“職位表”,如果還有其它...那即,當取得一條主體的完全數據時,那將進行幾十個表的聯接(join)操作。
如何解決呢?
通過分析上述問題,可以發現的一個特征是:這些信息類的內容都是需要動態維護的,但是所需的屬性是一樣的,對應的數據庫表中包含的字段也是一樣的。關鍵的字段就是兩個:“標識”和“名稱”。“標識”用於表示不變的主鍵,“名稱”用於表示程序界面上顯示的文字。
第二種數據字典就是為了解決上述問題而設計的。
還是以上面的例子為例。在系統中去掉《國籍表》、《證件表》、《學歷表》….,引入《系統代碼分類表》和《系統代碼表》:
《系統代碼分類表》
分類標識 分類名稱
Country 國籍
ID 證件
…
《系統代碼表》
標識 分類 內容
001 Contry 中國
002 Contry 美國
…..
501 ID 身份證
502 ID 暫住證
……
《系統代碼表》的“分類”字段都指向《系統代碼分類表》中的“分類標識”。這樣,在程序需要獲得國籍信息時,只要通過“Country”這個標識去《系統代碼表》中檢索就可以了。這樣的設計也便於建立一個單獨的程序模塊來維護所有的這些公共信息。
對於《職員表》,使用第一種數據字典時,其表結構是:
職員ID、姓名、國籍ID、證件ID、學歷ID…….
采用第二種數據字典后,其表結構是:
職員ID、姓名
另外增加《屬性表》,該表是《職員表》和《系統代碼表》的關系表,其表結構是:
屬性ID、職員ID、系統代碼表_標識
如:
《職員表》
職員ID 姓名
1 張三
2 李四
…..
《屬性表》
屬性ID 職員ID 系統代碼表_標識
1 1 001 (表示張三是中國籍)
2 1 501 (表示張三的證件是身份證)
3 2 002 (表示李四是美國籍)
4 2 501 (表示李四的證件是身份證)
…..
可以看出《職員表》的設計大為簡化,系統也更加靈活了,完全可以適應主體屬性的大量變更了。程序的設計應用第二種數據字典時和數據庫表的方法一樣。
數據字典的優點
一, 在一定程度上,通過系統維護人員即可改變系統的行為(功能),不需要開發人員的介入。使得系統的變化更快,能及時響應客戶和市場的需求。
二, 提高了系統的靈活性、通用性,減少了主體和屬性的耦合度
三, 簡化了主體類的業務邏輯
四, 能減少對系統程序的改動,使數據庫、程序和頁面更穩定。特別是數據量大的時候,能大幅減少開發工作量
五, 使數據庫表結構和程序結構條理上更清楚,更容易理解,在可開發性、可擴展性、可維護性、系統強壯性上都有優勢。
數據字典的缺點
1, 數據字典是通用的設計,在系統效率上會低一些。
2, 程序算法相對復雜一些。
3, 對於開發人員,需要具備一定抽象思維能力,所以對開發人員的要求較高。
所以,當屬性的數量不多時,用第一種數據字典即可。對於大型的,未定型的系統,可以采用第二種數據字典來設計。至於具體的系統里怎么設計,還是要在看實際情況來找尋通用性和效率二者間的平衡。無論怎么做,關系理論和范式仍是基礎。
數據字典的一般設計
下面給出一個用數據庫實現的第二種數據字典表的設計。要注意這個設計不是唯一的,完全可以用XML、字符串等形式來設計數據字典。
數據字典表(Dictionary):
字段名 |
類型 |
說明 |
編號 |
Char(16) |
間斷增量(Not Null,PK) |
分類名稱 |
Varchar(64) |
用來進行過濾選取字典表相關域 |
內容 |
Varchar(255) |
|
父級編號 |
Char(16) |
取Dictionary的編號(FK),用來進行等級設計。使之成為樹型結構。 |