層次關(guān)系數(shù)據(jù)庫(kù)表的設(shè)計(jì)
數(shù)據(jù)層次的概念:數(shù)據(jù)層次是表達(dá)數(shù)據(jù)的一種重要關(guān)系,在數(shù)據(jù)庫(kù)的設(shè)計(jì)中,如:組織結(jié)構(gòu)分解、工作任務(wù)分解、行政區(qū)劃的分解等都是層次關(guān)系數(shù)據(jù)的典型實(shí)例。
表達(dá)層次關(guān)系的數(shù)據(jù)一般需要實(shí)現(xiàn)如下屬性:
1.層次的最大級(jí)聯(lián)層次數(shù)。如:中國(guó)->湖南省->長(zhǎng)沙市->雨花區(qū),就是4層。
2.能反映同一層次之間的順序關(guān)系。如:長(zhǎng)沙市 必須在 衡陽(yáng)市的前面,(因?yàn)槠涫鞘?huì))。
3.能獲取任意層次的父節(jié)點(diǎn)級(jí)子節(jié)點(diǎn)(子節(jié)點(diǎn)集)。
4.直接獲取任意層次的數(shù)據(jù)。比如:第三層 市級(jí)別的數(shù)據(jù)。
5.能方便構(gòu)造層次關(guān)系表達(dá)樹。
6.層次結(jié)構(gòu)及排序方式的改變不影響其其他數(shù)據(jù)的內(nèi)部邏輯關(guān)系。
一般有三種方式來(lái)表現(xiàn)層次關(guān)系的數(shù)據(jù):
1.建立多個(gè)數(shù)據(jù)庫(kù)表:
如: COUNTRY: ID(主鍵) COUNTRY_NAME
PROVINCE: ID(主鍵) COUNTRY_ID(外鍵),PROVINCE_NAME
CITY: ID(主鍵), PROVINCE_ID(外鍵),CITY_NAME
此種方式比較簡(jiǎn)單,但設(shè)計(jì)的靈活性不夠,數(shù)據(jù)處理起來(lái)比較麻煩。
2.采用表的自關(guān)聯(lián)外鍵引用
如: DISTRICT_INFO: ID(主鍵),PARENT_ID,(外鍵)DISTRICT_INFO
通過(guò)外鍵(PARENT_ID)的自身引用主鍵(ID)來(lái)確立層次關(guān)系。
優(yōu)點(diǎn):無(wú)限級(jí)別的層次關(guān)系,擴(kuò)充性強(qiáng)。對(duì)于Oracle數(shù)據(jù)庫(kù)來(lái)說(shuō),能簡(jiǎn)單通過(guò) Start With,,,Connect By--語(yǔ)句來(lái)實(shí)現(xiàn)數(shù)據(jù)的查詢。
缺點(diǎn):不能明確看出層次關(guān)系,無(wú)法實(shí)現(xiàn)排序。
3.采用編碼方式來(lái)實(shí)現(xiàn)層次
DISTRICT: ID,CODE,NAME 其中CODE的特點(diǎn)是上級(jí)編碼是下級(jí)編碼的前綴
優(yōu)點(diǎn):通過(guò)編碼的內(nèi)容能夠很容易回去數(shù)據(jù)的層次關(guān)系。
缺點(diǎn):使用Like方法或函數(shù)查詢來(lái)實(shí)現(xiàn)子集的查找,效率較低,能實(shí)現(xiàn)層次關(guān)系的級(jí)數(shù)有限(受CODE的字段長(zhǎng)度影響)。
優(yōu)化方案:
集合2,3的優(yōu)點(diǎn),采用固定編碼級(jí)次的長(zhǎng)度的方法來(lái)設(shè)計(jì)表。
DISTRICT:ID,CODE,PARENT_ID,NAME
其中ID為主鍵,CODE:規(guī)定為4位一級(jí)。表現(xiàn)的數(shù)據(jù)如下:
|
從數(shù)據(jù)中可以看出,PARENT_ID可以直觀表達(dá)層次的上下級(jí)關(guān)系
而編碼CODE可以直觀表達(dá)層次關(guān)系與同一層次的順序關(guān)系。
如果要將長(zhǎng)沙排在衡陽(yáng)的前面,需要對(duì)調(diào)其編碼即可,而外部的引用關(guān)系由于通過(guò)ID實(shí)現(xiàn),不會(huì)受其影響。
獲取節(jié)點(diǎn)的父級(jí)別節(jié)點(diǎn):
Select * From DISTRICT Where ID=(Select PARENT_ID From DISTRICT Where ID=2)
獲取節(jié)點(diǎn)的子級(jí)別節(jié)點(diǎn)列表:
Select * From DISTRICT Where PARENT_ID=2
獲取所有的子節(jié)點(diǎn)信息:
Select level, * From DISTRICT d Start With PARENT_ID=2 Connect By d.PARENT_ID=Prior t.ID
或 --排序模式
Select * From DISTRICT d Where d.CODE Like '00010001%' Order By CODE
獲取某一層次(N)的節(jié)點(diǎn)信息(實(shí)現(xiàn)排序,層次碼長(zhǎng)度固定的意義):
Select * From DISTRICT Where LENGTH(CODE)=4*N And CODE Like '0001%' Order By CODE......
posted on 2008-08-26 11:29 都市淘沙者 閱讀(4398) 評(píng)論(0) 編輯 收藏 所屬分類: Oracle/Mysql/Postgres/