MySQL之表的约束
一 介紹
約束條件與數(shù)據(jù)類(lèi)型的寬度一樣,都是可選參數(shù)
作用:用于保證數(shù)據(jù)的完整性和一致性
主要分為:
?
說(shuō)明:
1. 是否允許為空,默認(rèn)NULL,可設(shè)置NOT NULL,字段不允許為空,必須賦值 2. 字段是否有默認(rèn)值,缺省的默認(rèn)值是NULL,如果插入記錄時(shí)不給字段賦值,此字段使用默認(rèn)值 sex enum('male','female') not null default 'male' age int unsigned NOT NULL default 20 必須為正值(無(wú)符號(hào)) 不允許為空 默認(rèn)是20 3. 是否是key 主鍵 primary key 外鍵 foreign key 索引 (index,unique...)二 not null與default
是否可空,null表示空,非字符串
not null - 不可空
null - 可空
默認(rèn)值,創(chuàng)建列時(shí)可以指定默認(rèn)值,當(dāng)插入數(shù)據(jù)時(shí)如果未主動(dòng)設(shè)置,則自動(dòng)添加默認(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 | | +-------+---------+------+-----+---------+-------+ 1 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字段的值不為空且唯一
一個(gè)表中可以:
單列做主鍵
多列做主鍵(復(fù)合主鍵)
但一個(gè)表內(nèi)只能有一個(gè)主鍵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)#方法二:在某一個(gè)字段后用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)#方法三:在所有字段后單獨(dú)定義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 | | +--------------+-------------+------+-----+---------+-------+ 3 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
約束字段為自動(dòng)增長(zhǎng),被約束的字段必須同時(shí)被key約束
#不指定id,則自動(dòng)增長(zhǎng) 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 | +----+------+--------+#對(duì)于自增的字段,在用delete刪除后,再插入值,該字段仍按照刪除前的位置繼續(xù)增長(zhǎng) 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是直接清空表,在刪除大表時(shí)用它 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 | +----+------+------+ 1 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)建表時(shí)指定auto_increment的初始值,注意初始值的設(shè)置為表選項(xiàng),應(yīng)該放到括號(hào)外 create table student( id int primary key auto_increment, name varchar(20), sex enum('male','female') default 'male' )auto_increment=3;#設(shè)置步長(zhǎng) sqlserver:自增步長(zhǎng)基于表級(jí)別create table t1(id int。。。)engine=innodb,auto_increment=2 步長(zhǎng)=2 default charset=utf8mysql自增的步長(zhǎng):show session variables like 'auto_inc%';#基于會(huì)話級(jí)別set session auth_increment_increment=2 #修改會(huì)話級(jí)別的步長(zhǎng)#基于全局級(jí)別的set global auth_increment_increment=2 #修改全局級(jí)別的步長(zhǎng)(所有會(huì)話都生效)#!!!注意了注意了注意了!!! 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的值會(huì)被忽略 比如:設(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 | +----+-------+------+ 步長(zhǎng)increment與起始偏移量offset:auto_increment_increment,auto_increment_offset六 foreign key
一 快速理解foreign key
員工信息表有三個(gè)字段:工號(hào) ?姓名 ?部門(mén)
公司有3個(gè)部門(mén),但是有1個(gè)億的員工,那意味著部門(mén)這個(gè)字段需要重復(fù)存儲(chǔ),部門(mén)名字越長(zhǎng),越浪費(fèi)
解決方法:
我們完全可以定義一個(gè)部門(mén)表
然后讓員工信息表關(guān)聯(lián)該表,如何關(guān)聯(lián),即foreign key
#表類(lèi)型必須是innodb存儲(chǔ)引擎,且被關(guān)聯(lián)的字段,即references指定的另外一個(gè)表的字段,必須保證唯一 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,'歐德博愛(ài)技術(shù)有限事業(yè)部'), (2,'艾利克斯人力資源部'), (3,'銷(xiāo)售部');#再往子表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中對(duì)應(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中對(duì)應(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 | +----+-------+--------+ 示范?二?如何找出兩張表之間的關(guān)系?
分析步驟: #1、先站在左表的角度去找 是否左表的多條記錄可以對(duì)應(yīng)右表的一條記錄,如果是,則證明左表的一個(gè)字段foreign key 右表一個(gè)字段(通常是id)#2、再站在右表的角度去找 是否右表的多條記錄可以對(duì)應(yīng)左表的一條記錄,如果是,則證明右表的一個(gè)字段foreign key 左表一個(gè)字段(通常是id)#3、總結(jié): #多對(duì)一: 如果只有步驟1成立,則是左表多對(duì)一右表 如果只有步驟2成立,則是右表多對(duì)一左表#多對(duì)多 如果步驟1和2同時(shí)成立,則證明這兩張表時(shí)一個(gè)雙向的多對(duì)一,即多對(duì)多,需要定義一個(gè)這兩張表的關(guān)系表來(lái)專(zhuān)門(mén)存放二者的關(guān)系#一對(duì)一: 如果1和2都不成立,而是左表的一條記錄唯一對(duì)應(yīng)右表的一條記錄,反之亦然。這種情況很簡(jiǎn)單,就是在左表foreign key右表的基礎(chǔ)上,將左表的外鍵字段設(shè)置成unique即可三 建立表之間的關(guān)系
#一對(duì)多或稱(chēng)為多對(duì)一 三張表:出版社,作者信息,書(shū)一對(duì)多(或多對(duì)一):一個(gè)出版社可以出版多本書(shū)關(guān)聯(lián)方式:foreign key =====================多對(duì)一===================== 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è)地雷出版社'), ('人民音樂(lè)不好聽(tīng)出版社'), ('知識(shí)產(chǎn)權(quán)沒(méi)有用出版社') ;insert into book(name,press_id) values ('九陽(yáng)神功',1), ('九陰真經(jīng)',2), ('九陰白骨爪',2), ('獨(dú)孤九劍',3), ('降龍十巴掌',2), ('葵花寶典',3) ; View Code 一夫多妻制#妻子表的丈夫id外鍵到丈夫表的id 其他例子??
#多對(duì)多 三張表:出版社,作者信息,書(shū)多對(duì)多:一個(gè)作者可以寫(xiě)多本書(shū),一本書(shū)也可以有多個(gè)作者,雙向的一對(duì)多,即多對(duì)多關(guān)聯(lián)方式:foreign key+一張新的表 =====================多對(duì)多===================== create table author( id int primary key auto_increment, name varchar(20) );#這張表就存放作者表與書(shū)表的關(guān)系,即查詢(xú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) );#插入四個(gè)作者,id依次排開(kāi) insert into author(name) values('egon'),('alex'),('yuanhao'),('wpq');#每個(gè)作者與自己的代表作如下 1 egon: 1 九陽(yáng)神功2 九陰真經(jīng)3 九陰白骨爪4 獨(dú)孤九劍5 降龍十巴掌6 葵花寶典2 alex: 1 九陽(yáng)神功6 葵花寶典3 yuanhao:4 獨(dú)孤九劍5 降龍十巴掌6 葵花寶典4 wpq:1 九陽(yáng)神功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 單張表:用戶(hù)表+相親關(guān)系表,相當(dāng)于:用戶(hù)表+相親關(guān)系表+用戶(hù)表 多張表:用戶(hù)表+用戶(hù)與主機(jī)關(guān)系表+主機(jī)表中間那一張存放關(guān)系的表,對(duì)外關(guān)聯(lián)的字段可以聯(lián)合唯一 其他例子?
#一對(duì)一 兩張表:學(xué)生表和客戶(hù)表一對(duì)一:一個(gè)學(xué)生是一個(gè)客戶(hù),一個(gè)客戶(hù)有可能變成一個(gè)學(xué)校,即一對(duì)一的關(guān)系關(guān)聯(lián)方式:foreign key+unique #一定是student來(lái)foreign key表customer,這樣就保證了: #1 學(xué)生一定是一個(gè)客戶(hù), #2 客戶(hù)不一定是學(xué)生,但有可能成為一個(gè)學(xué)生 create table customer( id int primary key auto_increment, name varchar(20) not null, qq varchar(10) not null, phone char(16) not null );create table student( id int primary key auto_increment, class_name varchar(20) not null, customer_id int unique, #該字段一定要是唯一的 foreign key(customer_id) references customer(id) #外鍵的字段一定要保證unique on delete cascade on update cascade );#增加客戶(hù) insert into customer(name,qq,phone) values ('李飛機(jī)','31811231',13811341220), ('王大炮','123123123',15213146809), ('守榴彈','283818181',1867141331), ('吳坦克','283818181',1851143312), ('贏火箭','888818181',1861243314), ('戰(zhàn)地雷','112312312',18811431230) ;#增加學(xué)生 insert into student(class_name,customer_id) values ('脫產(chǎn)3班',3), ('周末19期',4), ('周末19期',5) ; View Code 例一:一個(gè)用戶(hù)只有一個(gè)博客用戶(hù)表:id name1 egon2 alex3 wupeiqi博客表 fk+uniqueid url name_id1 xxxx 12 yyyy 33 zzz 2例二:一個(gè)管理員唯一對(duì)應(yīng)一個(gè)用戶(hù)用戶(hù)表:id user password1 egon xxxx2 alex yyyy管理員表:fk+uniqueid user_id password1 1 xxxxx2 2 yyyyy轉(zhuǎn)載于:https://www.cnblogs.com/fu-yong/p/8495003.html
總結(jié)
以上是生活随笔為你收集整理的MySQL之表的约束的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 梦到去看香的算卦是什么意思
- 下一篇: SQL Server中SCAN 和SEE