MySQL之表的约束
生活随笔
收集整理的這篇文章主要介紹了
MySQL之表的约束
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一 介紹
約束條件與數據類型的寬度一樣,都是可選參數
作用:用于保證數據的完整性和一致性
主要分為:
?
說明:
1. 是否允許為空,默認NULL,可設置NOT NULL,字段不允許為空,必須賦值 2. 字段是否有默認值,缺省的默認值是NULL,如果插入記錄時不給字段賦值,此字段使用默認值 sex enum('male','female') not null default 'male' age int unsigned NOT NULL default 20 必須為正值(無符號) 不允許為空 默認是20 3. 是否是key 主鍵 primary key 外鍵 foreign key 索引 (index,unique...)二 not null與default
是否可空,null表示空,非字符串
not null - 不可空
null - 可空
默認值,創建列時可以指定默認值,當插入數據時如果未主動設置,則自動添加默認值
create table tb1(
nid int not null defalut 2,
num int not null
)
三 unique
============設置唯一約束 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','技術'); Query OK, 1 row affected (0.00 sec) mysql> insert into department1 values(1,'IT','技術'); 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的化學反應 create table service( id int primary key auto_increment, name varchar(20), host varchar(15) not null, port int not null, unique(host,port) #聯合唯一 );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' 聯合唯一四 primary key
primary key字段的值不為空且唯一
一個表中可以:
單列做主鍵
多列做主鍵(復合主鍵)
但一個表內只能有一個主鍵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); #創建主鍵并為其命名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
約束字段為自動增長,被約束的字段必須同時被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刪除后,再插入值,該字段仍按照刪除前的位置繼續增長 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 | +----+------+------+#應該用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 | +----+------+------+ 1 row in set (0.00 sec) View Code #在創建完表后,修改自增字段的起始值 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#也可以創建表時指定auto_increment的初始值,注意初始值的設置為表選項,應該放到括號外 create table student( id int primary key auto_increment, name varchar(20), sex enum('male','female') default 'male' )auto_increment=3;#設置步長 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的值會被忽略 比如:設置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
一 快速理解foreign key
員工信息表有三個字段:工號 ?姓名 ?部門
公司有3個部門,但是有1個億的員工,那意味著部門這個字段需要重復存儲,部門名字越長,越浪費
解決方法:
我們完全可以定義一個部門表
然后讓員工信息表關聯該表,如何關聯,即foreign key
#表類型必須是innodb存儲引擎,且被關聯的字段,即references指定的另外一個表的字段,必須保證唯一 create table department( id int primary key, name varchar(20) not null )engine=innodb;#dpt_id外鍵,關聯父表(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,'歐德博愛技術有限事業部'), (2,'艾利克斯人力資源部'), (3,'銷售部');#再往子表employee中插入記錄 insert into employee values (1,'egon',1), (2,'alex1',2), (3,'alex2',2), (4,'alex3',2), (5,'李坦克',3), (6,'劉飛機',3), (7,'張火箭',3), (8,'林子彈',3), (9,'加特林',3) ;#刪父表department,子表employee中對應的記錄跟著刪 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中對應的記錄跟著改 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 右表一個字段(通常是id)#2、再站在右表的角度去找 是否右表的多條記錄可以對應左表的一條記錄,如果是,則證明右表的一個字段foreign key 左表一個字段(通常是id)#3、總結: #多對一: 如果只有步驟1成立,則是左表多對一右表 如果只有步驟2成立,則是右表多對一左表#多對多 如果步驟1和2同時成立,則證明這兩張表時一個雙向的多對一,即多對多,需要定義一個這兩張表的關系表來專門存放二者的關系#一對一: 如果1和2都不成立,而是左表的一條記錄唯一對應右表的一條記錄,反之亦然。這種情況很簡單,就是在左表foreign key右表的基礎上,將左表的外鍵字段設置成unique即可三 建立表之間的關系
#一對多或稱為多對一 三張表:出版社,作者信息,書一對多(或多對一):一個出版社可以出版多本書關聯方式: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 ('北京工業地雷出版社'), ('人民音樂不好聽出版社'), ('知識產權沒有用出版社') ;insert into book(name,press_id) values ('九陽神功',1), ('九陰真經',2), ('九陰白骨爪',2), ('獨孤九劍',3), ('降龍十巴掌',2), ('葵花寶典',3) ; View Code 一夫多妻制#妻子表的丈夫id外鍵到丈夫表的id 其他例子??
#多對多 三張表:出版社,作者信息,書多對多:一個作者可以寫多本書,一本書也可以有多個作者,雙向的一對多,即多對多關聯方式:foreign key+一張新的表 =====================多對多===================== create table author( id int primary key auto_increment, name varchar(20) );#這張表就存放作者表與書表的關系,即查詢二者的關系查這表就可以了 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');#每個作者與自己的代表作如下 1 egon: 1 九陽神功2 九陰真經3 九陰白骨爪4 獨孤九劍5 降龍十巴掌6 葵花寶典2 alex: 1 九陽神功6 葵花寶典3 yuanhao:4 獨孤九劍5 降龍十巴掌6 葵花寶典4 wpq:1 九陽神功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 單張表:用戶表+相親關系表,相當于:用戶表+相親關系表+用戶表 多張表:用戶表+用戶與主機關系表+主機表中間那一張存放關系的表,對外關聯的字段可以聯合唯一 其他例子?
#一對一 兩張表:學生表和客戶表一對一:一個學生是一個客戶,一個客戶有可能變成一個學校,即一對一的關系關聯方式:foreign key+unique #一定是student來foreign key表customer,這樣就保證了: #1 學生一定是一個客戶, #2 客戶不一定是學生,但有可能成為一個學生 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 );#增加客戶 insert into customer(name,qq,phone) values ('李飛機','31811231',13811341220), ('王大炮','123123123',15213146809), ('守榴彈','283818181',1867141331), ('吳坦克','283818181',1851143312), ('贏火箭','888818181',1861243314), ('戰地雷','112312312',18811431230) ;#增加學生 insert into student(class_name,customer_id) values ('脫產3班',3), ('周末19期',4), ('周末19期',5) ; View Code 例一:一個用戶只有一個博客用戶表:id name1 egon2 alex3 wupeiqi博客表 fk+uniqueid url name_id1 xxxx 12 yyyy 33 zzz 2例二:一個管理員唯一對應一個用戶用戶表:id user password1 egon xxxx2 alex yyyy管理員表:fk+uniqueid user_id password1 1 xxxxx2 2 yyyyy轉載于:https://www.cnblogs.com/fu-yong/p/8495003.html
總結
以上是生活随笔為你收集整理的MySQL之表的约束的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到去看香的算卦是什么意思
- 下一篇: SQL Server中SCAN 和SEE