15-3 完整性約束介紹

一 約束條件介紹:
約束條件與數據類型的寬度同樣,都是可選參數

做用:用於保證數據的完整性和一致性
主要分爲:
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 keymysql> 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 keymysql> 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: 0mysql> 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: 0mysql> 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: 0mysql> 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便可
相關文章
相關標籤/搜索