約束問題總結

剛開始接觸約束時,可能對它產生了一些困惑,比如說一張表中可以有幾個不同的約束,一張表中的同一列可以有幾個不同的約束,還有約束在列級和表級定義等等問題。

 

一.約束種類

   首先,來看一下約束的種類,ORACLE支持五種類型的完整性約束:

1.NOT NULL (非空)——防止NULL值進入指定的列在單列基礎上定義,默認情況下,ORACLE允許在任何列中有NULL


2.CHECK (檢查)--檢查在約束中指定的條件是否得到了滿足


3.UNIQUE (唯一)——保證在指定的列中沒有重複值在該表中每一個值或者每一組值都將是唯一的,但允許NULL插入;


4.PRIMARY KEY (主鍵)——用來唯一的標識出表的每一行,並且防止出現NULL


5.FOREIGN KEY (外部鍵)——通過使用公共列在表之間建立一種父子(parent-child)關係

 

二.約束的定義

   

約束的定義分爲列級和表級;

 

1.對於NOT NULL約束,它只能在列級定義;

如下:

SQL> create table dept(deptno number not null);

Table created.

 

在表級定義是不正確的:

 

SQL> create table dept(deptno number(2,0),

  2  constraint dept_deptno_notnull  not null(deptno));

constraint dept_deptno_notnull  not null(deptno))

                                *

ERROR at line 2:

ORA-00904: : invalid identifier

或者使用alter  table 命令來添加約束:

SQL> create table dept(deptno number(2,0));

Table created.

SQL> alter table dept modify deptno not null;

Table altered.

 

 

2.對於CHECK約束,它可以在表級和列級定義;

 

列級定義如下:

SQL> create  table dept(deptno  number(2,0)  constraint dept_deptno_ck  check(deptno   between 10  and  999));

Table created.

 

對於表級定義如下:

SQL> create  table dept(deptno  number(2,0),

  2   constraint dept_deptno_ck  check(deptno   between 10  and  999));

Table created.

 

 

或者使用alter  table 命令來添加約束:

SQL> create table dept(deptno  number(2,0));

Table created.

SQL> alter table dept add constraint dept_deptno_ck check(deptno between  10  and 999);

Table altered.

 

3.對於UNIQUE約束,它可以在表級和列級定義;

 

列級定義如下:

SQL> create table dept(deptno number(2,0) constraint dept_deptno_uq unique);

Table created.

 

對於表級定義如下:

SQL> create table dept(deptno number(2,0),

  2  constraint dept_deptno_uq unique(deptno));

Table created.

 

 

或者使用alter  table 命令來添加約束:

SQL> create table dept(deptno number(2,0));

Table created.

SQL> alter table dept add constraint dept_deptno_uq unique(deptno);

Table altered.

 

4.對於PRIMARY KEY約束,它可以在表級和列級定義;

 

列級定義如下:

 

SQL> create  table dept(deptno number(2,0)  constraint dept_deptno_pk  primary key); 

Table created.

 

 

對於表級定義如下:

 

SQL> create  table dept(deptno number(2,0) , 

  2  constraint dept_deptno_pk primary key(deptno));

Table created.

 

或者使用alter  table 命令來添加約束:

 

SQL> create table dept(deptno number(2,0));

Table created.

SQL> alter table dept add constraint dept_deptno_pk  primary  key(deptno);

Table altered.

 

5.對於FOREIGN KEY約束,它可以在表級和列級定義;

 

列級定義如下:

SQL> create table dept(deptno  number(2,0)   constraint dept_deptno_pk  primary key);

Table created.

SQL> create  table  dept1(deptno  number(2,0)   constraint dept1_deptno_fk  references dept(deptno));

Table created.

 

表級定義如下:

SQL> create table  dept(deptno  number(2,0)   constraint   dept_deptno_pk  primary  key);

Table created.

SQL> create  table  dept1(deptno  number(2,0),

  2  constraint dept1_deptno_fk  foreign   key(deptno)   references dept(deptno));

Table created.

 

或者使用alter  table 命令來添加約束:

SQL> create table  dept(deptno  number(2,0)   constraint   dept_deptno_pk  primary  key);

Table created.

SQL> create  table dept1(deptno number(2,0));

Table created.

SQL> alter table dept1  add constraint dept1_deptno_fk  foreign  key(deptno)  references  dept(deptno);

Table altered.

 

 

三.約束問題總結

1.NOT  NULL約束,如果要求一組列都具這個約束,則不能爲整個組定義NOT NULL約束,而必須對每個列單獨定義NOT NULL約束;

 

2.CHECK約束,無法使用子查詢來計算值是否被允許,也無法使用諸如SYSDATE函數;

 

3.UNIQUE約束,可以對單列或者多列定義,對於多列時,不需要這些列數據類型相同,也  不需要相鄰;

 

4.PRIMARY KEY約束,可以對單列或者多列定義,它相當於UNIQUENOT  NULL的組合,但是每個表中只能有一個PK約束,但是可以有任意數量的UNIQUENOT NULL的約束列;

 

5.對於FOREIGN KEY約束,這個約束在子表中定義的列(或者多列)對應父表中的主鍵列。這些列不需要同名,但數據類型必須相同。什麼樣的表可以作爲父表?這個要具有UNIQUE或者是PRIMARY KEY約束的表。FOREIGN KEY約束還有個特點,就是可以插入NULL值,即使在父表中沒有NULL值的情況下。

 

6.對於開始的問題,一張表中可以有幾個不同的約束,這個可以分爲兩種情況,第一,在表中不同列的約束,如果在不同列有兩個PRIMARY KEY是不允許的,其它情況都是可以的,比如可以一列是PK,一列是UNIQUE。第二,在表中同一列中,如果同一列同時有PRIMARY KEYUNIQUE是不允許的,其它情況都是可以的,比如這一列既是UNIQUE又是FOREIGN KEY

 

7.對於創建約束時自動創建索引問題補充

這個是對上次寫的補充,(主鍵約束自動建立索引問題)

在上面所說的五種約束中,只有PKUNIQUE約束在創建時,產生唯一性索引,

SQL> create table  dept(deptno  number(2,0)   constraint   dept_deptno_pk  primary  key);

SQL> select index_name  from  user_indexes;

INDEX_NAME

------------------------------

DEPT_DEPTNO_PK

JHIST_EMP_ID_ST_DATE_PK

JHIST_JOB_IX

 

 

可以看到產生了索引;

deptdeptno列上創建索引,會產生錯誤,是因爲在建立PRIMARY KEY約束時已經創建了索引;

 

SQL> create index  tt  on  dept(deptno);

create index  tt  on  dept(deptno)

                           *

ERROR at line 1:

ORA-01408: such column list already indexed

 

把兩個列作爲主鍵,

 

SQL> create  table dept(deptno   number(2,0),dname varchar2(12),constraint deptno_dname_pk  primary  key(deptno,dname));

Table created.

 

在上表中的其中一列建立索引,可以成功。

 

SQL> create  index  tt  on  dept(dname);

Index created.

     

發佈了39 篇原創文章 · 獲贊 2 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章