一 約束條件介紹:
約束條件與數據類型的寬度同樣,都是可選參數
做用:用於保證數據的完整性和一致性
主要分爲:
PRIMARY KEY (PK) 標識該字段爲該表的主鍵,能夠惟一的標識記錄
FOREIGN KEY (FK) 標識該字段爲該表的外鍵
NOT NULL 標識該字段不能爲空
UNIQUE KEY (UK) 標識該字段的值是惟一的
AUTO_INCREMENT 標識該字段的值自動增加(整數類型,並且爲主鍵)
DEFAULT 爲該字段設置默認值
UNSIGNED 無符號
ZEROFILL 使用0填充
二 not null與default
not null - 不可空
null - 可空
默認值,建立列時能夠指定默認值,當插入數據時若是未主動設置,則自動添加默認值
create table tb1(
nid int not null defalut 2,
num int not null
)
1 null
mysql> create table t1(id int); Query OK, 0 rows affected (0.50 sec) mysql> desc t1; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | +-------+---------+------+-----+---------+-------+ 1 row in set (0.01 sec) mysql> insert into t1 values(); Query OK, 1 row affected (0.10 sec)
2 not null
mysql> create table t2(id int not null); Query OK, 0 rows affected (0.64 sec) mysql> desc t2; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | id | int(11) | NO | | NULL | | +-------+---------+------+-----+---------+-------+ 1 row in set (0.00 sec) 再次插入空報錯: mysql> insert into t2 values(); ERROR 1364 (HY000): Field 'id' doesn't have a default value
3 defalut
#設置id字段有默認值後,則不管id字段是null仍是not null,均可以插入空,插入空默認填入default指定的默認值
mysql> create table t3(id int default 1); mysql> insert into t3 values(); Query OK, 1 row affected (0.09 sec) mysql> select * from t3; +----+ | id | +----+ | 1 | +----+ 1 row in set (0.00 sec) 能夠再次更改: mysql> alter table t3 modify id int not null default 1;
三 unique惟一,不重複
1 uniqe:
建立一個表 mysql> create table department1( -> id int, -> name varchar(20) unique, -> comment varchar(100) -> ); Query OK, 0 rows affected (0.69 sec) 插入數據 mysql> insert into department1 values(1,'IT','技術'); Query OK, 1 row affected (0.10 sec) 再次插入數據報錯: mysql> insert into department1 values(1,'IT','技術'); ERROR 1062 (23000): Duplicate entry 'IT' for key 'name'
2 uniqe和not null 至關於主鍵 primary key
mysql> create table t4(id int not null unique); Query OK, 0 rows affected (0.61 sec) mysql> desc t4; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | +-------+---------+------+-----+---------+-------+ 1 row in set (0.01 sec)
3 聯合惟一 unique
mysql> create table service( -> id int primary key auto_increment, -> name varchar(20), -> host varchar(15) not null, -> port int not null, -> unique(host,port) #聯合惟一 -> ); Query OK, 0 rows affected (0.69 sec) 插入數據: 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); 再次插入報錯: mysql> 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字段的值不爲空且惟一,那咱們直接使用not null+unique不就能夠了嗎,要它幹什麼?
主鍵primary key是innodb存儲引擎組織數據的依據,innodb稱之爲索引組織表,一張表中必須有且只有一個主鍵。
一個表中能夠:
單列作主鍵
多列作主鍵(複合主鍵)
1 單列作主鍵
方法1: mysql> create table t5(id int not null unique,name varchar(20) not null unique,comment varchar(100)); Query OK, 0 rows affected (0.63 sec) mysql> desc t5; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | NO | UNI | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ 3 rows in set (0.01 sec) 方法2:在某一個字段後用primary key mysql> create table t6(id int primary key unique,name varchar(20),comment varchar(100)); Query OK, 0 rows affected (0.70 sec) mysql> desc t6; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | YES | | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ 3 rows in set (0.01 sec) 方法3:在全部字段後單獨定義primary key mysql> create table t7(id int,name varchar(20),comment varchar(100),constraint pk_name primary key(id));#建立主鍵併爲其命名pk_name Query OK, 0 rows affected (0.64 sec) mysql> desc t7; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | YES | | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ 3 rows in set (0.01 sec)
2 多列作主鍵(複合主鍵)
mysql> create table t8(ip varchar(15),port char(5),service_name varchar(10) not null,primary key(ip,port)); Query OK, 0 rows affected (0.58 sec) mysql> desc t8; +--------------+-------------+------+-----+---------+-------+ | 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.01 sec) 插入數據: mysql> insert into t8 values('172.16.45.10','3306','mysqld'),('172.16.45.11','3306','mariadb'); Query OK, 2 rows affected (0.33 sec) Records: 2 Duplicates: 0 Warnings: 0 再次插入數據報錯: mysql> insert into service values ('172.16.45.10','3306','nginx'); ERROR 1136 (21S01): Column count doesn't match value count at row 1
五 auto_increment
約束字段爲自動增加,被約束的字段必須同時被key約束
1 不指定id
mysql> create table student(id int primary key auto_increment,name varchar(20),sex enum('male','female') default 'male'); Query OK, 0 rows affected (0.96 sec) 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 | | +-------+-----------------------+------+-----+---------+----------------+ 3 rows in set (0.01 sec) mysql> insert into student(name) values -> ('egon'), -> ('alex') -> ; Query OK, 2 rows affected (0.35 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from student; +----+------+------+ | id | name | sex | +----+------+------+ | 1 | egon | male | | 2 | alex | male | +----+------+------+ 2 rows in set (0.00 sec)
2 指定id
mysql> insert into student values(4,'taibai','female'); Query OK, 1 row affected (0.33 sec) mysql> select * from student; +----+--------+--------+ | id | name | sex | +----+--------+--------+ | 1 | egon | male | | 2 | alex | male | | 4 | taibai | female | +----+--------+--------+ 3 rows in set (0.00 sec)
3 刪除id後,會不會重新開始自增?
#對於自增的字段,在用delete刪除後,再插入值,該字段仍按照刪除前的位置繼續增加 mysql> delete from student; Query OK, 3 rows affected (0.37 sec) mysql> select * from student; Empty set (0.00 sec) mysql> insert into student(name) values('ysb'); Query OK, 1 row affected (0.09 sec) mysql> select * from student; +----+------+------+ | id | name | sex | +----+------+------+ | 5 | ysb | male | +----+------+------+ 1 row in set (0.00 sec) #若是用truncate是接清空表,那麼表的id會重新開始計算 例子: mysql> truncate student; Query OK, 0 rows affected (0.54 sec) mysql> select * from student; Empty set (0.00 sec) mysql> insert into student(name) values('egon'); Query OK, 1 row affected (0.33 sec) mysql> select * from student; +----+------+------+ | id | name | sex | +----+------+------+ | 1 | egon | male | +----+------+------+ 1 row in set (0.00 sec)
六 foreign key 用於關聯
1-1 快速理解foreign key
1 建立父表
#表類型必須是innodb存儲引擎,且被關聯的字段,即references指定的另一個表的字段,必須保證惟一
mysql> create table department( -> id int primary key, -> name varchar(20) not null -> )engine=innodb; Query OK, 0 rows affected (0.60 sec)
2 建立子表:
#dpt_id外鍵,關聯父表(department主鍵id),同步更新,同步刪除
mysql> 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; Query OK, 0 rows affected (0.34 sec)
分別再插入數據:
mysql> insert into department values -> (1,'歐德博愛技術有限事業部'), -> (2,'艾利克斯人力資源部'), -> (3,'銷售部'); Query OK, 3 rows affected (0.09 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> 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) -> ; Query OK, 9 rows affected (0.19 sec) Records: 9 Duplicates: 0 Warnings: 0
#刪父表department,子表employee中對應的記錄跟着刪
mysql> delete from department where id=3; Query OK, 1 row affected (0.45 sec) mysql> select * from employee; +----+-------+--------+ | id | name | dpt_id | +----+-------+--------+ | 1 | egon | 1 | | 2 | alex1 | 2 | | 3 | alex2 | 2 | | 4 | alex3 | 2 | +----+-------+--------+ 4 rows in set (0.00 sec)
#更新父表department,子表employee中對應的記錄跟着改
mysql> update department set id=22222 where id=2; Query OK, 1 row affected (0.37 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from employee; +----+-------+--------+ | id | name | dpt_id | +----+-------+--------+ | 1 | egon | 1 | | 2 | alex1 | 22222 | | 3 | alex2 | 22222 | | 4 | alex3 | 22222 | +----+-------+--------+ 4 rows in set (0.00 sec)
2-1 如何找出兩張表之間的關係分析步驟:#一、先站在左表的角度去找是否左表的多條記錄能夠對應右表的一條記錄,若是是,則證實左表的一個字段foreign key 右表一個字段(一般是id)#二、再站在右表的角度去找是否右表的多條記錄能夠對應左表的一條記錄,若是是,則證實右表的一個字段foreign key 左表一個字段(一般是id)#三、總結:#多對一:若是隻有步驟1成立,則是左表多對一右表若是隻有步驟2成立,則是右表多對一左表#多對多若是步驟1和2同時成立,則證實這兩張表時一個雙向的多對一,即多對多,須要定義一個這兩張表的關係表來專門存放兩者的關係#一對一:若是1和2都不成立,而是左表的一條記錄惟一對應右表的一條記錄,反之亦然。這種狀況很簡單,就是在左表foreign key右表的基礎上,將左表的外鍵字段設置成unique便可