概览
约束是一种限制,通过对表的行或列的数据做出限制,来确保表的数据完整性和唯一性
为了防止不符合规范的数据进入数据库,在用户对数据进行插入、修改、删除等操作时,DBMS自动按照一定的约束条件对数据进行监测,使不符合规范的数据不能进入数据库,以确保数据库中存储的数据正确、有效、相容。
约束条件与数据类型的宽度一样,都是可选参数,主要分为以下几种:
# NOT NULL :非空约束,指定某列不能为空;
# UNIQUE : 唯一约束,指定某列或者几列组合不能重复
# PRIMARY KEY :主键,指定该列的值可以唯一地标识该列记录
# FOREIGN KEY :外键,指定该行记录从属于主表中的一条记录,主要用于参照完整性
NOT NULL
是否可空,null表示空,非字符串
not null - 不可空,若用户未指定值,系统会报错 列表 数据类型 not null
null - 可空
mysql> create table t12 (id int not null);
Query OK,0 rows affected (0.02sec)
mysql> select * fromt12;
Emptyset (0.00sec)
mysql>desc t12;+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00sec)
#不能向id列插入空元素。
mysql> insert into t12 values (null);
ERROR1048 (23000): Column 'id' cannot be nullmysql> insert into t12 values (1);
Query OK,1 row affected (0.01 sec)
-------------------------------------------------------
修改表指定列添加非空约束
alter table 表名 modify 列名 数据类型 not null;
删除非空约束
alter table 表名 modify 列名 数据类型;
UNIQUE
唯一约束,指定某列或者几列组合不能重复,要求列唯一,可以为空
方法一:定义完之后直接指定唯一约束
create table department1(
idint,
name varchar(20) unique,
comment varchar(100)
);
方法二:定义完所有列之后指定唯一约束
create table department2(
idint,
name varchar(20),
comment varchar(100),
unique(name)
);
mysql> insert into department1 values(1,'IT','技术');
Query OK,1 row affected (0.00sec)
mysql> insert into department1 values(1,'IT','技术');
ERROR1062 (23000): Duplicate entry 'IT' for key 'name'
-------------------------------------------------------
修改表时添加唯一约束
alter table 表名 modify 列名 数据类型 unique;
alter table 表名 add unique(列名);
alter table 表名 add constrain unique(列名);
--------------------------------------------------
删除唯一约束
alter table 表名 drop index 列名;
alter table 表名 drop key 列名;
not null 和unique的结合
mysql> create table t1(id int not nullunique);
Query OK,0 rows affected (0.02sec)
mysql>desc t1;+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
PRIMARY KEY
主键为了保证表中的每一条数据的该字段都是表格中的唯一值。换言之,它是用来独一无二地确认一个表格中的每一行数据。
主键可以包含一个字段或多个字段。当主键包含多个栏位时,称为组合键 (Composite Key),也可以叫联合主键。
主键可以在建置新表格时设定 (运用 CREATE TABLE 语句),或是以改变现有的表格架构方式设定 (运用 ALTER TABLE)。
主键必须唯一,主键值非空;可以是单一字段,也可以是多字段组合
主键的类型
主键分为单字段主键和多字段主键
单字段主键由一个字段(列)组成
1.在定义 的同时指定主键 列名 数据类型 primary key;
2,在列定义的后面指定主键 [constraint ] primary key [列名]
多字段联合主键(复合主键)
主键有多个字段联合组成 primary key (字段1,字段2....字段3)
例:
create table 表名(表名1 数据类型,
表名2 数据类型,
primary key(表名1,表名2));
通过修改表为列添加主键
alter table 表名 modify 列名 数据类型 primary key;
alter table 表名 modify add primary key (列名);
alter table 表名 modify add constrain primary key (列名);
删除主键
alter table 表名 drop primary key;
AUTO_INCREMENT
约束字段为自动增长,被约束的字段必须同时被key约束(auto_increment 应该紧跟primary key后面)
#不指定id,则自动增长
create table student(
idintprimary key auto_increment,
name varchar(20),
sexenum('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 * fromstudent;+----+------+------+
| id | name | sex |
+----+------+------+
| 1 | egon | male |
| 2 | alex | male |
+----+------+------+#也可以指定id
mysql> insert into student values(4,'asb','female');
Query OK,1 row affected (0.00sec)
mysql> insert into student values(7,'wsb','female');
Query OK,1 row affected (0.00sec)
mysql> select * fromstudent;+----+------+--------+
| id | name | sex |
+----+------+--------+
| 1 | egon | male |
| 2 | alex | male |
| 4 | asb | female |
| 7 | wsb | female |
+----+------+--------+#对于自增的字段,在用delete删除后,再插入值,该字段仍按照删除前的位置继续增长
#delete 只是删除插入的数值,并没有删除表中结构
mysql> delete fromstudent;
Query OK,4 rows affected (0.00sec)
mysql> select * fromstudent;
Emptyset (0.00sec)
mysql> insert into student(name) values('ysb');
mysql> select * fromstudent;+----+------+------+
| id | name | sex |
+----+------+------+
| 8 | ysb | male |
+----+------+------+#应该用truncate清空表,比起delete一条一条地删除记录,truncate是直接清空表,在删除大表时用它
mysql>truncate student;
Query OK,0 rows affected (0.01sec)
mysql> insert into student(name) values('egon');
Query OK,1 row affected (0.01sec)
mysql> select * fromstudent;+----+------+------+
| id | name | sex |
+----+------+------+
| 1 | egon | male |
+----+------+------+rowin set (0.00 sec)
FOREIKEY
外键:用于两个表的数据直接建立链接,可以是一列或者多列,一个表可以有多个外键
外键对应的是参照完整性,一个表的外键可以是空值,若不为空值,则每个外键必须等于另一个主键的某个值
使用外键约束: [constraint]foreign key (列名) reference (主键)修改表时添加外键约束: alter table 表名 add foreign key 列名 reference (主键)删除外键约束: alter table 表名 drop foreign key 列名
mysql> create table departments (dep_id int(4),dep_name varchar(11));
Query OK,0 rows affected (0.02sec)
mysql>desc departments;+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| dep_id | int(4) | YES | | NULL | |
| dep_name | varchar(11) | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
2 rows in set (0.00sec)
# 创建外键不成功
mysql> create table staff_info (s_id int,name varchar(20),dep_id int,foreign key(dep_id) references departments(dep_id));
ERROR1215(HY000): Cannot add foreign key
# 设置dep_id非空,仍然不能成功创建外键
mysql> alter table departments modify dep_id int(4) not null;
Query OK,0 rows affected (0.02sec)
Records:0 Duplicates: 0 Warnings: 0mysql>desc departments;+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| dep_id | int(4) | NO | | NULL | |
| dep_name | varchar(11) | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
2 rows in set (0.00sec)
mysql> create table staff_info (s_id int,name varchar(20),dep_id int,foreign key(dep_id) references departments(dep_id));
ERROR1215(HY000): Cannot add foreign key constraint
# 当设置字段为unique唯一字段时,设置该字段为外键成功
mysql> alter table departments modify dep_id int(4) unique;
Query OK,0 rows affected (0.01sec)
Records:0 Duplicates: 0 Warnings: 0mysql> desc departments; +----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| dep_id | int(4) | YES | UNI | NULL | |
| dep_name | varchar(11) | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
2 rows in set (0.01sec)
mysql> create table staff_info (s_id int,name varchar(20),dep_id int,foreign key(dep_id) references departments(dep_id));
Query OK,0 rows affected (0.02 sec)
外键约束参照:
cascade:从父类删除或更新,且自动删除或更新字表匹配的行
#表类型必须是innodb存储引擎,且被关联的字段,即references指定的另外一个表的字段,必须保证唯一
create table department(
idintprimary key,
name varchar(20) not null)engine=innodb;
#dpt_id外键,关联父表(department主键id),同步更新,同步删除
create table employee(
idintprimary key,
name varchar(20) not null,
dpt_idint,
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,'yuan',1),
(2,'nezha',2),
(3,'egon',2),
(4,'alex',2),
(5,'wusir',3),
(6,'李沁洋',3),
(7,'皮卡丘',3),
(8,'程咬金',3),
(9,'程咬银',3)
;
#删父表department,子表employee中对应的记录跟着删
mysql> delete from department where id=2;
Query OK,1 row affected (0.00sec)
mysql> select * fromemployee;+----+-----------+--------+
| id | name | dpt_id |
+----+-----------+--------+
| 1 | yuan | 1 |
| 5 | wusir | 3 |
| 6 | 李沁洋 | 3 |
| 7 | 皮卡丘 | 3 |
| 8 | 程咬金 | 3 |
| 9 | 程咬银 | 3 |
+----+-----------+--------+
6 rows in set (0.00sec)
#更新父表department,子表employee中对应的记录跟着改
mysql> update department set id=2 where id=3;
Query OK,1 row affected (0.01sec)
Rows matched:1 Changed: 1 Warnings: 0mysql> select * fromemployee;+----+-----------+--------+
| id | name | dpt_id |
+----+-----------+--------+
| 1 | yuan | 1 |
| 5 | wusir | 2 |
| 6 | 李沁洋 | 2 |
| 7 | 皮卡丘 | 2 |
| 8 | 程咬金 | 2 |
| 9 | 程咬银 | 2 |
+----+-----------+--------+
6 rows in set (0.00 sec)
-----------------------------------------------------------------------------------------------
主键约束与唯一约束的区别
一个表中可以有多个unique 声明,但只能有一个primary key 声明
声明primary key 的列不允许为空
unique允许为空
default 默认约束
默认约束指定某列的默认值
语法: 列名数据类型 defualt 默认值;
修改表时添加约束:
alter table 表名 modify 列名 数据类型 default 默认值;
alter table 表名 alter column 列名 set default 默认值;
删除约束
alter table 表名 modify 列名 数据类型 ;
alter table 表名 alter column 列名 drop default;