【MySQL】MySQL的約束

在開始以前,筆者介紹一下筆者使用的數據庫版本爲5.7。全部的關係型數據庫都支持對數據表使用約束,經過約束能夠更好的保證數據表裏數據的完整性。約束是在表上強制執行的數據校驗,約束主要用於保證數據庫裏數據的完整性。除此以外,當表中的數據存在相互依賴性時,能夠保護相關的數據不被刪除。java

大部分數據庫支持以下5種完整性約束。數據庫

  1. Not Null:非空約束
  2. UNIQUE:惟一約束
  3. PRIMARY KEY:主鍵
  4. FOREIGN KEY:外鍵
  5. CHECK:檢查

雖然大部分數據庫都支持上面5種約束,但MySQL不支持CHECK約束,雖然MySQL的SQL語句也可使用CHECK約束,但這個約束不會有任何做用。大部分約束均可以採用列級約束或者表級約束語法。spa

在MySQL的information_schema數據庫裏的table_constraints表來保存該數據庫實例中全部的約束信息,用戶能夠經過查詢table_constraints表來獲取該數據庫的約束信息。code

1.NOT NULL 約束

非空約束用於確保指定列不容許爲空,非空約束是比較特殊的約束,它只能做爲列級約束來使用,只能使用列級約束語法來定義。這裏要介紹一下SQL中的null值,SQL中的null值不區分大小寫。orm

create table hehe( #創建了非空約束,這意味着hehe_id不能爲null   hehe_id int not null, #MySQL的非空約束不能夠指定名字   hehe_name varchar(255) not null default 'xyz', #下面列能夠爲空,默認爲空   hehe_gender varchar(2) null );

除此以外,也能夠在使用alter table修改表時增長和刪除非空約束,SQL命令以下:blog

#增長非空約束 alter table hehe modify hehe_gender varchar(2) not null #取消非空約束 alter table hehe modify hehe_name varchar(2) null #取消非空約束,而且指定默認值 alter table hehe modify hehe_name varchar(225) default 'abc' null

 

2.UNIQUE 約束

惟一約束用於保證指定列或指定列組合不容許爲出現重複值。雖然惟一約束的列不能夠出現重複值,但能夠出現多個null值(由於在數據庫中null不等於null)。索引

同一個表內能夠建立多個惟一約束,惟一約束也能夠由多個列組合而成。ci

#建表時建立惟一約束,使用列級約束語法建立約束 create table unique_test( #創建了非空約束,這意味着test_id不能爲null test_id int not null, #unique就是惟一約束,使用列級約束語法自動建立惟一約束 test_name varchar(255) unique );

若是想爲多列組合創建惟一索引,或者想自行指定約束名稱,則須要使用表級約束語法。表級約束的語法爲:rem

[constraint 約束名] 約束定義

表級約束的語法格式既能夠放到create table語句中,也能夠放到alter table 語句中用add關鍵字來添加。io

#建表時建立惟一約束,使用表級約束語法創建約束 create table unique_test2( #創建了非空約束,這意味着test_id不能夠爲null test_id int not null, test_name varchar(255), test_pass varchar(255), #使用表級約束創建惟一約束 unique(test_name), #使用表級約束語法創建惟一約束,並且指定約束名 constraint test2_uk unique(test_pass) );

上面的建表語句爲test_name,test_pass分別創建了惟一索引,這意味着這兩列都不能出現重複值。除此以外,還能夠爲這兩列組合創建惟一索引。

#建表時建立惟一索引,使用表級約束語法創建索引 create table unique_test3( #創建了非空約束,這意味着test_id不能夠爲null test_id int not null, test_name varchar(255), test_pass varchar(255), #使用表級約束語法創建惟一約束,指定兩列組合不容許爲重複 constraint test3_uk unique(test_name,test_pass) );

也能夠在修改表結構的時候使用add關鍵字來增長惟一索引,

#增長惟一約束 alter table unique_test3 add unique(test_name,test_pass);

還能夠在修改表時,指定modify關鍵字

#爲unique test3表的test_name列增長惟一約束 alter table unique_test3 modify test_name varchar(255) unique;

 

3.PRIMARY KEY 約束

主鍵約束至關於非空約束和惟一約束,即主鍵約束的即不運行出現重複值,也不運行出現null值。主鍵的列值用於惟一標識表中的一條記錄。

每一個表中最多容許有一個主鍵,但這個主鍵約束能夠由多個數據列組合而成,主鍵是表中能惟一肯定一行記錄的字段或是字段組合。

注:MySQl運行在創建主鍵約束時爲該約束命名,但這個名字沒有任何做用,這是爲了保持與標準的SQL的兼容性。但部分數據庫都容許自行指定主鍵的名字,可是MySQL無論用戶爲主鍵約束命名,它老是把全部的主鍵約束命名爲PRIMARY。

不少數據庫對組件列都支持一種自增加的特性,若是某個數據列的類型是整型,並且該列做爲主鍵列,則可指定該列爲具備自增加功能。指定自增加功能一般用於邏輯主鍵列,該列沒有任何物理意義,僅僅爲了標識每一行。MySQl使用auto_increment來設置自增加。

create table primary_test4( #創建主鍵列,使用自增加 test_id int auto_increment primary key, test_name varchar(255), test_pass varchar(255) );

 

4.FOREIGN KEY 約束

外鍵約束主要用於保證一個或兩個數據表之間的參照完整性,外鍵是構建一個表的兩個字段或是兩個表的兩個字段之間的參照關係。外鍵確保了相關的兩個字段的參照關係:子(從)表外鍵列的值必須在主表被參照列的值範圍以內,或者爲空(也能夠經過非空約束來約束外鍵列不容許爲空)。

當主表記錄被從表記錄參照時,主表記錄不容許被刪除,必需先把從表裏參照該記錄的全部記錄都刪除後,才能夠刪除主表的該記錄。還有一種方式,刪除主表記錄時級聯刪除從表中全部參照該記錄的全部記錄。

從表外鍵參照的只能是主表主鍵列或者惟一鍵列,這樣才能夠保證從表記錄能夠準肯定位到被參照的主表記錄。同一個表內能夠擁有多個外鍵。

創建外鍵約束時,MySQL也會該列創建索引。

外鍵約束一般用於定義兩個實體之間的一對多,一對一的關聯關係。對於一對多的關聯關係,一般在多的一端增長外鍵列,列如老師-學生(假設一個老師對應多個學生,但每一個學生只有一個老師,這是典型的一對多的關聯關係)。爲了創建他們之間的關聯關係,能夠在學生表中增長一個外鍵列,該列中保存此條學生記錄對應老師的主鍵。對於一對一的關聯關係,則能夠選擇任意一方來增長外鍵列,增長外鍵列的表被稱爲從表,只要爲外鍵列增長惟一約束就能夠表示一對一的關係了。對於多對多的關聯關係,則須要額外增長一個鏈接表來記錄他們之間的關聯關係。

創建外鍵約束一樣能夠採用列級約束語法和表級約束語法。若是僅對單獨的數據列創建外鍵約束,則可使用列級約束語法便可:若是須要對多列組合建立外鍵約束,或者須要爲外鍵約束指定名字,則必須採用表級約束。

#爲了保證從表參照的主表存在,一般應該先創建主表 create table teacher_table{ #auto_increment:表明數據庫的自動編號策略,一般用作數據表的邏輯主鍵 teacher_id int auto_increment, teacher_name varchar(255), primary key(teacher_id) } create table student_table{ #爲本表創建主鍵約束 student_id int auto_increment primary key, student_name varchar(255), #指定java_teacher 參照到 teacher_table的teacher_id列 java_teacher int references teacher_table(teacher_id) }

值得提出,雖然MySQL支持使用列級約束語法來創建外鍵約束,但這種約束語法創建的外鍵約束不會生效,MySQL提供這種約束語法僅僅是爲了和標準的SQL保持兼容。所以在MySQl要使用外鍵約束,應該使用表級約束。

#爲了保證從表參照的主表存在,一般應該先創建主表 create table teacher_table{ #auto_increment:表明數據庫的自動編號策略,一般用作數據表的邏輯主鍵 teacher_id int auto_increment, teacher_name varchar(255), primary key(teacher_id) } create table student_table{ #爲本表創建主鍵約束 student_id int auto_increment primary key, student_name varchar(255), #指定java_teacher 參照到 teacher_table的teacher_id列 java_teacher int, foreign key(java_teacher) references teacher_table(teacher_id) }

若是使用表級約束語法,則須要使用foreign key 來指定本表的外鍵列,並使用references來指定參照那個主表,以及參照到主表的那個數據列。使用表級約束語法能夠爲外鍵約束指定約束名,若是建立外鍵約束時沒有指定約束名稱,則MySQL會爲該外鍵約束命名爲table_name_ibfk_n,其中table_name是從表的表名,而n是從1開始的整數。

若是須要顯式指定外鍵約束的名稱,則應該使用constraint來指定名字。

#爲了保證從表參照的主表存在,一般應該先創建主表 create table teacher_table{ #auto_increment:表明數據庫的自動編號策略,一般用作數據表的邏輯主鍵 teacher_id int auto_increment, teacher_name varchar(255), primary key(teacher_id) } create table student_table{ #爲本表創建主鍵約束 student_id int auto_increment primary key, student_name varchar(255), #指定java_teacher 參照到 teacher_table的teacher_id列 java_teacher int, constraint student_teacher_fk foreign key(java_teacher) references teacher_table(teacher_id) }

若是須要創建多列組合的外鍵約束,則必須使用表級約束的語法

#爲了保證從表參照的主表存在,一般應該先創建主表 create table teacher_table2{ teacher_name varchar(255), teacher_pass varchar(255) primary key(teacher_name,teacher_pass) } create table student_table2{ #爲本表創建主鍵約束 student_id int auto_increment primary key, student_name varchar(255), java_teacher_name varchar(255), java_teacher_pass varchar(255), #使用表級約束語法,創建外鍵約束 foreign key(java_teacher_name,java_teacher_pass) references teacher_table2(teacher_name,teacher_pass); }

刪除外鍵約束的語法也很是簡單,在alter table後增長「drop foreign key 約束名」便可。

alter table student_table2 drop foreign key student_teacher_ibfk_1;

增長外鍵約束,一般使用add foreign key命令。

alter table student_table2 add foreign key(java_teacher_name,java_teacher_pass) references teacher_table2(teacher_name,teacher_pass);

值得提出的是,外加約束不只能夠參照其餘表,並且還能夠參照自身,這個參照自身的狀況一般被稱爲自關聯。列如,使用一個表保存某個公司的全部的員工,員工之間有部門經理和普通員工之分,部門經理和普通員工之間存在一對多的關聯關係,但他們都是保存在同一個數據表裏的記錄,這就是典型的自關聯。

#使用表級約束語法創建外約束鍵,參照自身 create table foreign_test( foreign_id int auto_increment primary key, foreign_name varchar(255), refer_id int, foreign key(refer_id) references foreign_test(foreign_id) );

若是想定義刪除主表記錄時,從表記錄也會隨之刪除,則須要在創建外鍵約束後添加on delete cascade或添加 on delete set null,第一種刪除主表記錄時,把參照該主表記錄的從表記錄所有級聯刪除;第二種是指定當刪除主鍵記錄時,把參照該主表記錄的的外鍵都設爲null。

#爲了保證從表參照的主表存在,一般應該先創建主表 create table teacher_table3{ teacher_name varchar(255), teacher_pass varchar(255) primary key(teacher_name,teacher_pass) } create table student_table3{ #爲本表創建主鍵約束 student_id int auto_increment primary key, student_name varchar(255), java_teacher_name varchar(255), java_teacher_pass varchar(255), #使用表級約束語法,創建外鍵約束 foreign key(java_teacher_name,java_teacher_pass) references teacher_table3(teacher_name,teacher_pass) on delete cascade; #也可使用on delete set null }

 

5.CHECK 約束

 當前版本的MySQL支持建表時指定CHECK約束,但這個CHEKC約束不會起任何做用。創建CHECK約束的語法很是簡單,只要在建表列定之後添加check(邏輯表達式)便可。

create table check_test( emp_id int primary key auto_increment, emp_name varchar(255), emp_salary decimal, check(emp_salary>0) );

而後使用以下的命令:

insert into check_test(emp_name,emp_salary) values('jame',10); insert into check_test(emp_name,emp_salary) values('jame',-10);

會發現這兩條數據均可以成功插入。

 

到這裏MySQL的約束就介紹完了,MySQL做爲一開源、免費的的數據庫系統,對有些功能的支持確實不太好。若是但願MySQL建立有CHECK約束的表或是具備跟複雜約束的表,能夠藉助MySQL的觸發機制來實現。

相關文章
相關標籤/搜索