mysql-表完整性约束
閱讀目錄
- 一 介紹
- 二 not null與default
- 三 unique
- 四 primary key
- 五 auto_increment
- 六 foreign key
- 七?總結(jié)
?
?
一 介紹
回到頂部
約束條件與數(shù)據(jù)類型的寬度一樣,都是可選參數(shù)
作用:用于保證數(shù)據(jù)的完整性和一致性
主要分為:
?
?
說明:
1. 是否允許為空,默認(rèn)NULL,可設(shè)置NOT NULL,字段不允許為空,必須賦值 2. 字段是否有默認(rèn)值,缺省的默認(rèn)值是NULL,如果插入記錄時不給字段賦值,此字段使用默認(rèn)值 sex enum('male','female') not null default 'male' age int unsigned NOT NULL default 20 必須為正值(無符號) 不允許為空 默認(rèn)是20 3. 是否是key 主鍵 primary key 外鍵 foreign key 索引 (index,unique...)二 not null與default
回到頂部
是否可空,null表示空,非字符串
not null - 不可空
null - 可空
默認(rèn)值,創(chuàng)建列時可以指定默認(rèn)值,當(dāng)插入數(shù)據(jù)時如果未主動設(shè)置,則自動添加默認(rèn)值
create table tb1(
nid int not null defalut 2,
num int not null)
三 unique
回到頂部
============設(shè)置唯一約束 UNIQUE=============== 方法一: create table department1( id int, name varchar(20) unique, comment varchar(100) );方法二: create table department2( id int, name varchar(20), comment varchar(100), constraint uk_name unique(name) );mysql> insert into department1 values(1,'IT','技術(shù)'); Query OK, 1 row affected (0.00 sec) mysql> insert into department1 values(1,'IT','技術(shù)'); ERROR 1062 (23000): Duplicate entry 'IT' for key 'name' View Code mysql> create table t1(id int not null unique); Query OK, 0 rows affected (0.02 sec)mysql> desc t1; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | +-------+---------+------+-----+---------+-------+ row in set (0.00 sec) not null+unique的化學(xué)反應(yīng) create table service( id int primary key auto_increment, name varchar(20), host varchar(15) not null, port int not null, unique(host,port) #聯(lián)合唯一 );mysql> insert into service values-> (1,'nginx','192.168.0.10',80),-> (2,'haproxy','192.168.0.20',80),-> (3,'mysql','192.168.0.30',3306)-> ; Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0mysql> insert into service(name,host,port) values('nginx','192.168.0.10',80); ERROR 1062 (23000): Duplicate entry '192.168.0.10-80' for key 'host' 聯(lián)合唯一四 primary key
回到頂部
primary key字段的值不為空且唯一
一個表中可以:
單列做主鍵
多列做主鍵(復(fù)合主鍵)
但一個表內(nèi)只能有一個主鍵primary key
============單列做主鍵=============== #方法一:not null+unique create table department1( id int not null unique, #主鍵 name varchar(20) not null unique, comment varchar(100) );mysql> desc department1; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | NO | UNI | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ rows in set (0.01 sec)#方法二:在某一個字段后用primary key create table department2( id int primary key, #主鍵 name varchar(20), comment varchar(100) );mysql> desc department2; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | YES | | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ rows in set (0.00 sec)#方法三:在所有字段后單獨定義primary key create table department3( id int, name varchar(20), comment varchar(100), constraint pk_name primary key(id); #創(chuàng)建主鍵并為其命名pk_name mysql> desc department3; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | YES | | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ rows in set (0.01 sec) 單列主鍵 ==================多列做主鍵================ create table service( ip varchar(15), port char(5), service_name varchar(10) not null, primary key(ip,port) );mysql> desc service; +--------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------+-------------+------+-----+---------+-------+ | ip | varchar(15) | NO | PRI | NULL | | | port | char(5) | NO | PRI | NULL | | | service_name | varchar(10) | NO | | NULL | | +--------------+-------------+------+-----+---------+-------+ rows in set (0.00 sec)mysql> insert into service values-> ('172.16.45.10','3306','mysqld'),-> ('172.16.45.11','3306','mariadb')-> ; Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0mysql> insert into service values ('172.16.45.10','3306','nginx'); ERROR 1062 (23000): Duplicate entry '172.16.45.10-3306' for key 'PRIMARY' 多列主鍵五 auto_increment
回到頂部
約束字段為自動增長,被約束的字段必須同時被key約束
#不指定id,則自動增長 create table student( id int primary key auto_increment, name varchar(20), sex enum('male','female') default 'male' );mysql> desc student; +-------+-----------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-----------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(20) | YES | | NULL | | | sex | enum('male','female') | YES | | male | | +-------+-----------------------+------+-----+---------+----------------+ mysql> insert into student(name) values-> ('egon'),-> ('alex')-> ;mysql> select * from student; +----+------+------+ | id | name | sex | +----+------+------+ | 1 | egon | male | | 2 | alex | male | +----+------+------+#也可以指定id mysql> insert into student values(4,'asb','female'); Query OK, 1 row affected (0.00 sec)mysql> insert into student values(7,'wsb','female'); Query OK, 1 row affected (0.00 sec)mysql> select * from student; +----+------+--------+ | id | name | sex | +----+------+--------+ | 1 | egon | male | | 2 | alex | male | | 4 | asb | female | | 7 | wsb | female | +----+------+--------+#對于自增的字段,在用delete刪除后,再插入值,該字段仍按照刪除前的位置繼續(xù)增長 mysql> delete from student; Query OK, 4 rows affected (0.00 sec)mysql> select * from student; Empty set (0.00 sec)mysql> insert into student(name) values('ysb'); mysql> select * from student; +----+------+------+ | id | name | sex | +----+------+------+ | 8 | ysb | male | +----+------+------+#應(yīng)該用truncate清空表,比起delete一條一條地刪除記錄,truncate是直接清空表,在刪除大表時用它 mysql> truncate student; Query OK, 0 rows affected (0.01 sec)mysql> insert into student(name) values('egon'); Query OK, 1 row affected (0.01 sec)mysql> select * from student; +----+------+------+ | id | name | sex | +----+------+------+ | 1 | egon | male | +----+------+------+ row in set (0.00 sec) View Code #在創(chuàng)建完表后,修改自增字段的起始值 mysql> create table student(-> id int primary key auto_increment,-> name varchar(20),-> sex enum('male','female') default 'male'-> );mysql> alter table student auto_increment=3;mysql> show create table student; ....... ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mysql> insert into student(name) values('egon'); Query OK, 1 row affected (0.01 sec)mysql> select * from student; +----+------+------+ | id | name | sex | +----+------+------+ | 3 | egon | male | +----+------+------+ row in set (0.00 sec)mysql> show create table student; ....... ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8#也可以創(chuàng)建表時指定auto_increment的初始值,注意初始值的設(shè)置為表選項,應(yīng)該放到括號外 create table student( id int primary key auto_increment, name varchar(20), sex enum('male','female') default 'male' )auto_increment=3;#設(shè)置步長 sqlserver:自增步長基于表級別create table t1(id int。。。)engine=innodb,auto_increment=2 步長=2 default charset=utf8mysql自增的步長:show session variables like 'auto_inc%';#基于會話級別set session auth_increment_increment=2 #修改會話級別的步長#基于全局級別的set global auth_increment_increment=2 #修改全局級別的步長(所有會話都生效)#!!!注意了注意了注意了!!! If the value of auto_increment_offset is greater than that of auto_increment_increment, the value of auto_increment_offset is ignored. 翻譯:如果auto_increment_offset的值大于auto_increment_increment的值,則auto_increment_offset的值會被忽略 比如:設(shè)置auto_increment_offset=3,auto_increment_increment=2mysql> set global auto_increment_increment=5; Query OK, 0 rows affected (0.00 sec)mysql> set global auto_increment_offset=3; Query OK, 0 rows affected (0.00 sec)mysql> show variables like 'auto_incre%'; #需要退出重新登錄 +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | auto_increment_increment | 1 | | auto_increment_offset | 1 | +--------------------------+-------+create table student( id int primary key auto_increment, name varchar(20), sex enum('male','female') default 'male' );mysql> insert into student(name) values('egon1'),('egon2'),('egon3'); mysql> select * from student; +----+-------+------+ | id | name | sex | +----+-------+------+ | 3 | egon1 | male | | 8 | egon2 | male | | 13 | egon3 | male | +----+-------+------+ 步長increment與起始偏移量offset:auto_increment_increment,auto_increment_offset六 foreign key
回到頂部
員工信息表有三個字段:工號 ?姓名 ?部門
公司有3個部門,但是有1個億的員工,那意味著部門這個字段需要重復(fù)存儲,部門名字越長,越浪費
解決方法:
我們完全可以定義一個部門表
然后讓員工信息表關(guān)聯(lián)該表,如何關(guān)聯(lián),即foreign key
#表類型必須是innodb存儲引擎,且被關(guān)聯(lián)的字段,即references指定的另外一個表的字段,必須是主鍵 create table department( id int primary key, name varchar(20) not null )engine=innodb;#dpt_id外鍵,關(guān)聯(lián)父表(department主鍵id),同步更新,同步刪除 create table employee( id int primary key, name varchar(20) not null, dpt_id int, constraint fk_name foreign key(dpt_id) references department(id) on delete cascade on update cascade )engine=innodb;#先往父表department中插入記錄 insert into department values (1,'歐德博愛技術(shù)有限事業(yè)部'), (2,'艾利克斯人力資源部'), (3,'銷售部');#再往子表employee中插入記錄 insert into employee values (1,'egon',1), (2,'alex1',2), (3,'alex2',2), (4,'alex3',2), (5,'李坦克',3), (6,'劉飛機(jī)',3), (7,'張火箭',3), (8,'林子彈',3), (9,'加特林',3) ;#刪父表department,子表employee中對應(yīng)的記錄跟著刪 mysql> delete from department where id=3; mysql> select * from employee; +----+-------+--------+ | id | name | dpt_id | +----+-------+--------+ | 1 | egon | 1 | | 2 | alex1 | 2 | | 3 | alex2 | 2 | | 4 | alex3 | 2 | +----+-------+--------+#更新父表department,子表employee中對應(yīng)的記錄跟著改 mysql> update department set id=22222 where id=2; mysql> select * from employee; +----+-------+--------+ | id | name | dpt_id | +----+-------+--------+ | 1 | egon | 1 | | 3 | alex2 | 22222 | | 4 | alex3 | 22222 | | 5 | alex1 | 22222 | +----+-------+--------+ 示范 表1 foreign key 表2 則表1的多條記錄對應(yīng)表2的一條記錄,即多對一利用foreign key的原理我們可以制作兩張表的多對多,一對一關(guān)系 多對多:表1的多條記錄可以對應(yīng)表2的一條記錄表2的多條記錄也可以對應(yīng)表1的一條記錄一對一:表1的一條記錄唯一對應(yīng)表2的一條記錄,反之亦然分析時,我們先從按照上面的基本原理去套,然后再翻譯成真實的意義,就很好理解了、、 輔助理解三張表:出版社,作者信息,書
一對多(或多對一):一個出版社可以出版多本書
關(guān)聯(lián)方式:foreign key
=====================多對一===================== create table press( id int primary key auto_increment, name varchar(20) );create table book( id int primary key auto_increment, name varchar(20), press_id int not null, foreign key(press_id) references press(id) on delete cascade on update cascade );insert into press(name) values ('北京工業(yè)地雷出版社'), ('人民音樂不好聽出版社'), ('知識產(chǎn)權(quán)沒有用出版社') ;insert into book(name,press_id) values ('九陽神功',1), ('九陰真經(jīng)',2), ('九陰白骨爪',2), ('獨孤九劍',3), ('降龍十巴掌',2), ('葵花寶典',3) ; View Code多對多:一個作者可以寫多本書,一本書也可以有多個作者,雙向的一對多,即多對多
關(guān)聯(lián)方式:foreign key+一張新的表
=====================多對多===================== create table author( id int primary key auto_increment, name varchar(20) );#這張表就存放作者表與書表的關(guān)系,即查詢二者的關(guān)系查這表就可以了 create table author2book( id int not null unique auto_increment, author_id int not null, book_id int not null, constraint fk_author foreign key(author_id) references author(id) on delete cascade on update cascade, constraint fk_book foreign key(book_id) references book(id) on delete cascade on update cascade, primary key(author_id,book_id) );#插入四個作者,id依次排開 insert into author(name) values('egon'),('alex'),('yuanhao'),('wpq');#每個作者與自己的代表作如下 egon: 九陽神功 九陰真經(jīng) 九陰白骨爪 獨孤九劍 降龍十巴掌 葵花寶典 alex: 九陽神功 葵花寶典 yuanhao: 獨孤九劍 降龍十巴掌 葵花寶典 wpq: 九陽神功insert into author2book(author_id,book_id) values (1,1), (1,2), (1,3), (1,4), (1,5), (1,6), (2,1), (2,6), (3,4), (3,5), (3,6), (4,1) ; View Code#兩張表:學(xué)生表和客戶表
一對一:一個學(xué)生是一個客戶,一個客戶有可能變成一個學(xué)校,即一對一的關(guān)系
關(guān)聯(lián)方式:foreign key+unique
#一定是student來foreign key表customer,這樣就保證了: #1 學(xué)生一定是一個客戶, #2 客戶不一定是學(xué)生,但有可能成為一個學(xué)生 create table customer( id int primary key auto_increment, name varchar(20) not null );create table student( id int primary key auto_increment, name varchar(20) not null, class_name varchar(20) not null default 'python自動化', level int default 1, customer_id int unique, #該字段一定要是唯一的 foreign key(customer_id) references customer(id) #外鍵的字段一定要保證unique on delete cascade on update cascade );#增加客戶 insert into customer(name) values ('李飛機(jī)'), ('王大炮'), ('守榴彈'), ('吳坦克'), ('贏火箭'), ('戰(zhàn)地雷') ;#增加學(xué)生 insert into student(name,customer_id) values ('李飛機(jī)',1), ('王大炮',2) ; View Code練習(xí):賬號信息表,用戶組,主機(jī)表,主機(jī)組
#用戶表 create table user( id int not null unique auto_increment, username varchar(20) not null, password varchar(50) not null, primary key(username,password) );insert into user(username,password) values ('root','123'), ('egon','456'), ('alex','alex3714') ;#用戶組表 create table usergroup( id int primary key auto_increment, groupname varchar(20) not null unique );insert into usergroup(groupname) values ('IT'), ('Sale'), ('Finance'), ('boss') ;#主機(jī)表 create table host( id int primary key auto_increment, ip char(15) not null unique default '127.0.0.1' );insert into host(ip) values ('172.16.45.2'), ('172.16.31.10'), ('172.16.45.3'), ('172.16.31.11'), ('172.10.45.3'), ('172.10.45.4'), ('172.10.45.5'), ('192.168.1.20'), ('192.168.1.21'), ('192.168.1.22'), ('192.168.2.23'), ('192.168.2.223'), ('192.168.2.24'), ('192.168.3.22'), ('192.168.3.23'), ('192.168.3.24') ;#業(yè)務(wù)線表 create table business( id int primary key auto_increment, business varchar(20) not null unique ); insert into business(business) values ('輕松貸'), ('隨便花'), ('大富翁'), ('窮一生') ;#建關(guān)系:user與usergroup create table user2usergroup( id int not null unique auto_increment, user_id int not null, group_id int not null, primary key(user_id,group_id), foreign key(user_id) references user(id), foreign key(group_id) references usergroup(id) );insert into user2usergroup(user_id,group_id) values (1,1), (1,2), (1,3), (1,4), (2,3), (2,4), (3,4) ;#建關(guān)系:host與business create table host2business( id int not null unique auto_increment, host_id int not null, business_id int not null, primary key(host_id,business_id), foreign key(host_id) references host(id), foreign key(business_id) references business(id) );insert into host2business(host_id,business_id) values (1,1), (1,2), (1,3), (2,2), (2,3), (3,4) ;#建關(guān)系:user與host create table user2host( id int not null unique auto_increment, user_id int not null, host_id int not null, primary key(user_id,host_id), foreign key(user_id) references user(id), foreign key(host_id) references host(id) );insert into user2host(user_id,host_id) values (1,1), (1,2), (1,3), (1,4), (1,5), (1,6), (1,7), (1,8), (1,9), (1,10), (1,11), (1,12), (1,13), (1,14), (1,15), (1,16), (2,2), (2,3), (2,4), (2,5), (3,10), (3,11), (3,12) ; View Code?
作業(yè):
七、總結(jié)
回到頂部
1 not null 與defaultcreate table student2( id int primary key auto_increment, name char(5), sex enum('male','female') not null default 'female' );insert into student2(name) values('alex');create table student3( id int primary key auto_increment, name char(5), age int not null default 30 );insert into student3(name) values('alex');2 unique #單列唯一 create table teacher( id int not null unique, name char(10) ); insert into teacher values(1,'egon'); insert into teacher values(1,'alex');#多列唯一 #255.255.255.255 create table services( id int primary key auto_increment, name char(10), host char(15), port int, constraint host_port unique(host,port) );insert into services values('ftp','192.168.20.17',8080); insert into services values('httpd','192.168.20.17',8081);#auto_increment_offset:偏移量 create table dep( id int primary key auto_increment, name char(10) ); insert into dep(name) values('IT'),('HR'),('SALE'),('Boss');create table dep1( id int primary key auto_increment, name char(10) )auto_increment=10; insert into dep1(name) values('IT'),('HR'),('SALE'),('Boss');#auto_increment_increment:步長 create table dep2( id int primary key auto_increment, name char(10) ); set session auto_increment_increment=2; #會話級,只對當(dāng)前會話有效 set global auto_increment_increment=2; #全局,對所有的會話都有效 insert into dep1(name) values('IT'),('HR'),('SALE'),('Boss');#auto_increment_offset:偏移量+auto_increment_increment:步長 注意:如果auto_increment_offset的值大于auto_increment_increment的值,則auto_increment_offset的值會被忽略 set session auto_increment_offset=2; set session auto_increment_increment=3; show variables like '%auto_in%';create table dep3( id int primary key auto_increment, name char(10) ); insert into dep3(name) values('IT'),('HR'),('SALE'),('Boss');#foreign key #!!!先建被關(guān)聯(lián)的表,并且被關(guān)聯(lián)的字段必須唯一 create table dep( id int primary key auto_increment, name varchar(50), comment varchar(100) );create table emp_info( id int primary key auto_increment, name varchar(20), dep_id int, constraint fk_depid_id foreign key(dep_id) references dep(id) on delete cascade on update cascade );#先給被關(guān)聯(lián)的表初始化記錄 insert into dep values (1,'歐德博愛技術(shù)有限事業(yè)部','說的好...'), (2,'艾利克斯人力資源部','招不到人'), (3,'銷售部','賣不出東西');insert into emp_info values (1,'egon',1), (2,'alex1',2), (3,'alex2',2), (4,'alex3',2), (5,'李坦克',3), (6,'劉飛機(jī)',3), (7,'張火箭',3), (8,'林子彈',3), (9,'加特林',3) ; View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/zhangningyang/p/7481504.html
總結(jié)
以上是默认站点為你收集整理的mysql-表完整性约束的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAVA: 序列化
- 下一篇: sql server和mysql的区别是