概览
约束是一种限制,通过对表的行或列的数据做出限制,来确保表的数据完整性和唯一性
为了防止不符合规范的数据进入数据库,在用户对数据进行插入、修改、删除等操作时,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.02 sec) mysql> select * from t12; Empty set (0.00 sec) mysql> desc t12; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | id | int(11) | NO | | NULL | | +-------+---------+------+-----+---------+-------+ 1 row in set (0.00 sec) #不能向id列插入空元素。 mysql> insert into t12 values (null); ERROR 1048 (23000): Column 'id' cannot be null mysql> 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( id int, name varchar(20) unique, comment varchar(100) ); 方法二:定义完所有列之后指定唯一约束 create table department2( id int, name varchar(20), comment varchar(100), 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'
-------------------------------------------------------
修改表时添加唯一约束
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 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)
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( 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删除后,再插入值,该字段仍按照删除前的位置继续增长
#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 | +----+------+------+ row in 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.02 sec) 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.00 sec) # 创建外键不成功 mysql> create table staff_info (s_id int,name varchar(20),dep_id int,foreign key(dep_id) references departments(dep_id)); ERROR 1215 (HY000): Cannot add foreign key # 设置dep_id非空,仍然不能成功创建外键 mysql> alter table departments modify dep_id int(4) not null; Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> 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.00 sec) mysql> create table staff_info (s_id int,name varchar(20),dep_id int,foreign key(dep_id) references departments(dep_id)); ERROR 1215 (HY000): Cannot add foreign key constraint # 当设置字段为unique唯一字段时,设置该字段为外键成功 mysql> alter table departments modify dep_id int(4) unique; Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> 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.01 sec) 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( 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, 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.00 sec) mysql> select * from employee; +----+-----------+--------+ | id | name | dpt_id | +----+-----------+--------+ | 1 | yuan | 1 | | 5 | wusir | 3 | | 6 | 李沁洋 | 3 | | 7 | 皮卡丘 | 3 | | 8 | 程咬金 | 3 | | 9 | 程咬银 | 3 | +----+-----------+--------+ 6 rows in set (0.00 sec) #更新父表department,子表employee中对应的记录跟着改 mysql> update department set id=2 where id=3; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from employee; +----+-----------+--------+ | 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;