Oracle數(shù)據(jù)庫(kù)表的完整性功能是一個(gè)非常實(shí)用的功能,利用這個(gè)功能可以提高表中數(shù)據(jù)的準(zhǔn)確率。根據(jù)其具體實(shí)現(xiàn)方式的不同,表的完整性包括三部分內(nèi)容,分別是實(shí)體完整性、域完整性與參照完整性。這三部分功能平時(shí)各負(fù)其責(zé),共同實(shí)現(xiàn)了表的完整性功能。
如現(xiàn)在有如下一張員工表格。若我們現(xiàn)在采用Oralce數(shù)據(jù)庫(kù)管理這張數(shù)據(jù)表,那我們?cè)撊绾谓Y(jié)合表的完整性功能,提高這張員工數(shù)據(jù)表的數(shù)據(jù)準(zhǔn)確率呢? 身份證號(hào)碼 姓名 入職日期 339005198103031716 甲 2008-2-1 339005198303031718 乙 2008-2-2 339005198003031719 丙 2008-2-3 339005198203031720 丁 2008-2-4 一、實(shí)體完整性。 實(shí)體完整性,是指在表的級(jí)別上,防止重復(fù)記錄的產(chǎn)生。如作為上面這一張員工信息表,其身份證號(hào)碼當(dāng)然不能重復(fù)。若輸入重復(fù)的話,則系統(tǒng)就應(yīng)該提示錯(cuò)誤信息。這就是通過(guò)實(shí)體完整性的功能來(lái)實(shí)現(xiàn)的。 具體的來(lái)說(shuō),表的實(shí)體完整性功能是通過(guò)主鍵來(lái)實(shí)現(xiàn)的。我們可以給表的某些字段設(shè)置主鍵,從而達(dá)到記錄不重復(fù)的目的。主鍵其有兩個(gè)特點(diǎn),一是不能為空,而是設(shè)置的主鍵的字段內(nèi)容不能重復(fù)。 從以上這張表中,我們可以把員工的身份證號(hào)碼設(shè)置為主鍵。如此,當(dāng)用戶數(shù)據(jù)身份證號(hào)碼時(shí),若輸入的身份證號(hào)碼重復(fù)的話,則數(shù)據(jù)庫(kù)系統(tǒng)會(huì)提醒用戶,數(shù)據(jù)的身份證號(hào)碼已經(jīng)存在,并且,這條記錄將不會(huì)被保存。 1、根據(jù)上面的要求在數(shù)據(jù)庫(kù)中創(chuàng)建表格。 2、在沒(méi)有創(chuàng)建主鍵,利用實(shí)體完整性功能之前,若數(shù)據(jù)的員工記錄具有相同的身份證號(hào)碼,系統(tǒng)也會(huì)接受,不會(huì)報(bào)錯(cuò)。如下圖所示。但這明顯不符合我們的要求。我們希望當(dāng)我們不小心輸入重復(fù)性的數(shù)據(jù)的時(shí)候,如身份證重復(fù)的話,則系統(tǒng)將提示錯(cuò)誤,并且,不保存該條記錄。 3、我們?cè)趧偛判陆ǖ穆毠け砩?,加上?shí)體完整性約束。給身份證號(hào)碼字段加上主鍵。然后,來(lái)看看具體的效果。 4、在身份證號(hào)碼上,我們實(shí)現(xiàn)完整性約束,建立主鍵后,我們發(fā)現(xiàn),此時(shí),在同時(shí)建立兩條相同的身份證號(hào)碼記錄的話,系統(tǒng)就提示錯(cuò)誤信息,所違反了唯一約束條件。從這里就可以看出,實(shí)體完整性約束在起作用了。 以上筆者描述的了就是Oracle服務(wù)器表完整性中的實(shí)體完整性的功能。通過(guò)這個(gè)過(guò)程的描述,我們可以看到,通過(guò)給表的某些字段設(shè)置主鍵的方法,我們可以實(shí)現(xiàn)對(duì)于表記錄的唯一性控制,從而防止用戶不小心輸入重復(fù)的數(shù)據(jù),造成數(shù)據(jù)庫(kù)中數(shù)據(jù)的混亂。 在給數(shù)據(jù)庫(kù)表實(shí)現(xiàn)實(shí)體完整性,即給表設(shè)置主鍵的時(shí)候,要注意幾個(gè)要點(diǎn)。 一是設(shè)置主鍵的字段是不允許為空的。所以,我們?cè)谠O(shè)計(jì)表結(jié)構(gòu)的時(shí)候,如果需要給表的某個(gè)字段設(shè)置成為主鍵的時(shí)候,則最好把這個(gè)字段設(shè)置為不為空。如此的話,用戶在操作數(shù)據(jù)表的時(shí)候,就一定要在該字段輸入值,否則的話,數(shù)據(jù)庫(kù)就會(huì)提示“該字段不能為空”的錯(cuò)誤。 二是設(shè)置主鍵后,該字段的內(nèi)容不能為重復(fù)。有時(shí)候,我們可能因?yàn)樵O(shè)計(jì)表格的時(shí)候,考慮的不夠周到,沒(méi)有把用戶表的身份證號(hào)碼字段設(shè)置為主鍵。若在表中已有數(shù)據(jù)的情況下,給表設(shè)置主鍵,就可能會(huì)發(fā)生錯(cuò)誤,因?yàn)楸碇械臄?shù)據(jù)可能已經(jīng)重復(fù)了。為此,我們最好在表設(shè)計(jì)的時(shí)候,就要考慮好,到底該字段是否要設(shè)置成為主鍵。 三是主鍵的設(shè)置根據(jù)不同的業(yè)務(wù)需求是不一樣的,數(shù)據(jù)庫(kù)管理員要根據(jù)實(shí)際的情況選擇恰當(dāng)?shù)淖侄巫鳛殛P(guān)鍵字。如在職工基本信息表中,我們可能要求身份證號(hào)碼唯一。但是,若在其他應(yīng)用中,若把身份證號(hào)碼設(shè)置為主鍵的話,就可能發(fā)生錯(cuò)誤。如在學(xué)校的學(xué)位管理中,可能一個(gè)人會(huì)同時(shí)取得兩個(gè)或者兩個(gè)以上的學(xué)位,此時(shí),若把身份證號(hào)碼設(shè)置為主鍵可能不是很合適。可能需要把身份證號(hào)碼與學(xué)會(huì)編號(hào)一起設(shè)置為主鍵。若同一張表中,有兩個(gè)以上的字段設(shè)置為主鍵時(shí),系統(tǒng)的要求是兩個(gè)字段都重復(fù)才是違反這個(gè)約束性條件。也就是說(shuō),學(xué)位表中有兩條記錄,身份證號(hào)碼相同學(xué)位編號(hào)不同(一個(gè)人同時(shí)有多個(gè)學(xué)位),這種情況是不違反實(shí)體完整性功能的。所以這要注意,跟設(shè)置單個(gè)主鍵有比較大的區(qū)別。單個(gè)主鍵是這個(gè)字段不能重復(fù),而多個(gè)主鍵的話,是設(shè)置主鍵的字段都不重復(fù)就行了。 二、參照完整性。 在一般的管理系統(tǒng)中,無(wú)論是小小的考勤系統(tǒng),還是大的ERP系統(tǒng),一般都會(huì)包含兩張表。一張是員工信息表,一張是部門信息表。如下表所示: 員工信息表
部門信息表
現(xiàn)在我們希望,在員工信息表處定義的部門信息必須存在與部門信息表中。也就是說(shuō),當(dāng)部門信息表中沒(méi)有定義這個(gè)部門的話,在員工信息表中將部門輸入這個(gè)部門。如在部門信息表里,我們沒(méi)有輸入研發(fā)部門,此時(shí),在員工信息表中,我們?nèi)舭岩粋€(gè)員工歸屬于研發(fā)部門的話,則系統(tǒng)要能夠提示錯(cuò)誤信息,告訴用戶這個(gè)部門還沒(méi)有定義,需要先定義該部門信息。 這個(gè)需求就是要通過(guò)參照完整性來(lái)實(shí)現(xiàn)。參照完整性是指互相關(guān)聯(lián)的兩個(gè)表之間的約束,具體的說(shuō),就是從表中每條記錄外鍵的值必須是主表中所存在的。因此,如果在兩個(gè)表之間建立了關(guān)聯(lián)關(guān)系,則對(duì)一個(gè)表進(jìn)行的操作要影響到另一個(gè)表中的記錄。下面,我結(jié)合具體的實(shí)例,講述一下參照完整性的具體實(shí)現(xiàn)方式及需要注意的地方。 1、 建立部門信息表。 SQL> create table DEPT(DETPNUM CHAR(10) not null,NAME varchar2(10) not null); 表建立完成以后,給部門信息表中插入銷售與采購(gòu)兩條記錄。 SQL> insert into DEPT values('SA','銷售'); SQL> insert into DEPT values('PR','采購(gòu)'); 技巧說(shuō)明:當(dāng)我們利用語(yǔ)句給一個(gè)表中插入記錄的時(shí)候,如果表中有兩個(gè)字段,我們給這兩個(gè)字段都賦值的話,則在插入語(yǔ)句中,可以不寫字段的名稱。但是,若插入一條記錄的時(shí)候,一條記錄的某個(gè)字段沒(méi)有賦值的話,則要注意一定要按賦值的順序把字段名一一寫清楚。 2、 建立員工信息表,先不設(shè)置外鍵,看效果如何。 SQL create table USERINFO(USERNUM CHAR(10) not null,SEX char(2),DEPTNUM CHAR(10)); 下面,我們給員工信息表插入一條記錄,部門為研發(fā)部門(AD)。該部門信息在部門信息表中不存在。在沒(méi)有建立參照完整性的條件下,數(shù)據(jù)庫(kù)將不會(huì)提示任何的錯(cuò)誤。 SQL> insert into USERINFO values('SA001','Y','AD'); 3、 給員工信息表實(shí)現(xiàn)參照完整性功能,給其部門字段設(shè)置外鍵。 從上面的記錄中可以看到,不設(shè)置外鍵的情況下,即使部門信息表中沒(méi)有這個(gè)部門信息,但是,在員工信息表中仍然可以把員工歸屬于“研發(fā)”部門。這在實(shí)際管理中,肯定會(huì)出亂子。所以,我們希望當(dāng)部門信息表中沒(méi)有研發(fā)部門的部門信息時(shí),員工信息表中就也不能出現(xiàn)這個(gè)部門。 我們先個(gè)員工信息表的部門字段定義一個(gè)外鍵。 SQL> ALTER TABLE USERINFO ADD CONSTRAINT FK_DEPTNUM FOREIGN KEY(DEPTNUM) REFERENCES DEPT(DETPNUM); ALTER TABLE USERINFO ADD CONSTRAINT FK_DEPTNUM FOREIGH KEY(DEPTNUM) REFERENCES DEPT(DETPNUM) 如圖所示,當(dāng)員工信息表中已經(jīng)有記錄,并且,該記錄的部門編號(hào)不存在與部門信息表中,在建立主鍵的時(shí)候,就會(huì)產(chǎn)生錯(cuò)誤信息,提示此列列表的唯一或主鍵不匹配。我先把該條記錄的部門信息更新一下,然后再建立主鍵。 SQL> ALTER TABLE USERINFO1 ADD CONSTRAINT FK_DEPTNUM FOREIGN KEY(DETPNUM)REFERENCES DEPT(DETPNUM); 這里要注意一個(gè)問(wèn)題,就是主表中的某個(gè)字段如果要被其他表設(shè)置為外鍵的話,則這個(gè)字段要先設(shè)置為主鍵,否則在建立外鍵的時(shí)候,會(huì)報(bào)錯(cuò)。 4、 給員工信息表插入記錄,部門字段不在部門信息表中,系統(tǒng)提示錯(cuò)誤信息。 SQL> insert into USERINFO values('SA001','Y','AD'); SQL> insert into USERINFO1 values('SA001','Y','AD'); 如上圖所示,沒(méi)有建立主鍵的員工信息表可以順利插入數(shù)據(jù),但是,在下面已經(jīng)建立了外鍵的表中的話,插入記錄的話,會(huì)提示錯(cuò)誤信息“違反完整約束條件,未找到父項(xiàng)關(guān)鍵字”。 5、 在參完整性的設(shè)計(jì)中,需要注意的幾個(gè)方面。 一是外鍵的取名規(guī)則。雖然在Oracle數(shù)據(jù)庫(kù)中,沒(méi)有對(duì)外鍵的取名有特殊的強(qiáng)制性要求,只要滿足普通的命名規(guī)則即可,如不能使用Oracle數(shù)據(jù)庫(kù)本身的關(guān)鍵字進(jìn)行命名或者名字不能以數(shù)字開(kāi)頭,除此之外,沒(méi)有強(qiáng)制性的要求。系統(tǒng)雖然沒(méi)有強(qiáng)制性要求,但是,作為一個(gè)好的數(shù)據(jù)庫(kù)開(kāi)發(fā)人員,要養(yǎng)成一個(gè)好的命名習(xí)慣。如按照我們一般的命名習(xí)慣,外鍵約束取名以FK開(kāi)頭,并用下劃線與名字進(jìn)行分開(kāi);名字一般是以字段名進(jìn)行定義。如上面給員工信息表的部門字段設(shè)置外鍵的話,去外鍵就取名為FK_DEP。如此的話,以后我們維護(hù)這些完整性功能的話,一看約束名字,就知道這個(gè)約束是參照完整性約束,其是作用在部門這個(gè)字段上。這個(gè)命名的另外一個(gè)好處,就是方便其他開(kāi)發(fā)人查詢?,F(xiàn)在的數(shù)據(jù)庫(kù)管理系統(tǒng)一般一個(gè)人很難完成,都是需要通過(guò)一個(gè)團(tuán)隊(duì)才可以實(shí)現(xiàn)。所以,我們?cè)谠O(shè)計(jì)數(shù)據(jù)庫(kù)的時(shí)候,不僅我們自己要能夠看懂我們?nèi)サ拿?,而且,其他開(kāi)發(fā)人員也需要能夠一目了然的知道這個(gè)名字的意思。不僅外鍵定義是如此,我們上面所說(shuō)的主鍵的定義,及后面將要講到的CHECK約束,都是類似的道理。 二是參照完整性約束中,一般把兩張表叫做主表與從表。主表就是被參考的表,就是上面例子中所講的“部門信息表”,而從表就是“員工信息表”。在設(shè)計(jì)參照完整性功能的時(shí)候,我們要注意的的是,主表中被參考的字段與從表中被定義為外鍵的字段,無(wú)論是數(shù)據(jù)類型還是數(shù)據(jù)的長(zhǎng)度都必須一致。否則的話,容易產(chǎn)生錯(cuò)誤。這也是一種數(shù)據(jù)庫(kù)開(kāi)發(fā)的良好習(xí)慣。 三是一單主表中的某個(gè)字段被其他表作為外鍵的話,則這個(gè)表的修改與刪除就會(huì)收到限制。一般情況下,這個(gè)被其他表引用了的字段將不能被刪除或者修改。用戶強(qiáng)行刪除的話,系統(tǒng)會(huì)提示該表已經(jīng)有子記錄。當(dāng)然,也可以通過(guò)“級(jí)聯(lián)修改”或者“級(jí)聯(lián)刪除”實(shí)現(xiàn)這個(gè)功能。級(jí)聯(lián)修改是指主表中字段內(nèi)容修改了,則從表中對(duì)應(yīng)的內(nèi)容也發(fā)生改變,如當(dāng)采購(gòu)部門名稱改為物流部門的話,則在員工信息表中的采購(gòu)部門也會(huì)自動(dòng)改為物流部門;級(jí)聯(lián)刪除也是類似的道理,到主表中的記錄被刪除的話,從表中的記錄也將被刪除,當(dāng)我把部門信息表中的采購(gòu)部門這條記錄刪除之后,員工信息表中的所有采購(gòu)部門的員工記錄也將被刪除。但是,很明顯,這么操作的話,比較危險(xiǎn)。所以,筆者一般都不建議如此操作。關(guān)于這個(gè)級(jí)聯(lián)修改及級(jí)聯(lián)刪除功能或后續(xù)還會(huì)詳細(xì)介紹。 |
|
來(lái)自: wwwijhyt圖書館 > 《數(shù)據(jù)庫(kù)》