MYSQL 表的完整性约束

概述

	为了防止不符合规范的数据进入数据库,在用户对数据进行插入、修改、删除等操作时,DBMS自动按照一定的约束条件对数据进行监测,使不符合规范的数据不能进入数据库,以确保数据库中存储的数据正确、有效、相容。 

  约束条件与数据类型的宽度一样,都是可选参数,主要分为以下几种:
NOT NULL         # 非空约束,指定某列不能为空; 
UNIQUE           # 唯一约束,指定某列或者几列组合不能重复
PRIMARY KEY      # 主键,指定该列的值可以唯一地标识该列记录
FOREIGN KEY      # 外键,指定该行记录从属于主表中的一条记录,主要用于参照完整性

NOT NULL

not null     # 不可为空
null         # 可以为空

create table t1 (id int(4) not null)

UNIQUE

唯一约束, 指定某列或者几列组不能重复

create table t1 (id int(10) unique);

create table t1 (id int(5) not null unique);   # not null unique == primary key

create table service(
id int primary key auto_increment,
host varchar(15) not null,
port int not null,
unique(host,port)    # 联合唯一
);

PRIMARY KEY

	主键为了保证表中的每一条数据的该字段都是表格中的唯一值。它是用来独一无二地确认一个表格中的每一行数据。 
	主键可以包含一个字段或多个字段。当主键包含多个栏位时,称为组合键,也可以叫联合主键。
	主键可以在建置新表格时设定 (运用 CREATE TABLE 语句),或是以改变现有的表格架构方式设定 (运用 ALTER TABLE)。
	主键必须唯一,主键值非空;可以是单一字段,也可以是多字段组合。
	
可以设置多个非空 + 唯一 (not null + unique)
删除主键
alter table 表名 drop primary key;

单字段主键

1. not null + unique  # 主键且只有一个主键 (id)
create table t1 (id int(5) not null unique, name varchar(32) not null unique);

2. primary key        # 主键
create table t1 (id int primary key);

3. 在所有字段后单独定义 primary key
create table t1 (id int, name varchar(9) primary key(id));

多字段主键

1. name字段可能会出现重复,所以加上ID字段来保证记录的唯一性

create table service(id int, name varchar(32), age int, primary key(id,name));

mysql> insert into service values
    -> ('172.16.45.10','3306','mysqld'),
    -> ('172.16.45.11','3306','mariadb')
    -> ;
    
mysql> 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约束

create table t1 (id int primary key auto_increment, sex("男", "女") default "男");

添加数据时可以指定id, 也可以不指定

对于自增的字段,在用delete删除后,再插入值,该字段仍按照删除前的位置继续增长

应该用 truncate是直接清空表,再进行添加id, 会从1开始记录

offset 偏移量

步长: auto_increment_increment
起始偏移量: auto_increment_offset

create table t1 (id int primary key auto_increment,name varchar(20));

1. 设置自增字段起始值
alter table t1 auto_increment = 3;

2. 建表时指定初始值, 注意初始值的设置为表选项,应该放到括号外
create table t1 (id int primary key auto_increment,name varchar(20))auto_increment=3;

3. 设置步长: auth_increment_increment (基于表级别的)
create table t1 (id int auto_increment)engine=innodb, auto_increment=2 步长=2;

# 基于会话级别
set session auth_increment_increment=2  # 修改会话级别的步长

# 基于全局级别的
set global auth_increment_increment=2   # 修改全局级别的步长(所有会话都生效)

注意:
如果 auto_increment_offset 的值大于 auto_increment_increment 的值,则auto_increment_offset的值会被忽略.

FOREIKEY

1. 概述
	如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,外键表示了两个关系之间的相关联系。以另一个关系的外键作主关键字的表被称为主表,具有此外键的表被称为主表的从表。外键又称作外关键字。
	
2. 外键约束
MySQL通过外键约束来保证表与表之间的数据的完整性和准确性。

3. 基本概念

1) MySQL中“键”和“索引”的定义相同,所以外键和主键一样也是索引的一种。不同的是MySQL会自动为所有表的主键进行索引,但是外键字段必须由用户进行明确的索引。用于外键关系的字段必须在所有的参照表中进行明确地索引,InnoDB不能自动地创建索引。

2) 外键可以是一对一的,一个表的记录只能与另一个表的一条记录连接,或者是一对多的,一个表的记录与另一个表的多条记录连接。

3) 如果需要更好的性能,并且不需要完整性检查,可以选择使用MyISAM表类型,如果想要在MySQL中根据参照完整性来建立表并且希望在此基础上保持良好的性能,最好选择表结构为innoDB类型。

4. 外键的使用条件

1) 两个表必须是InnoDB表,MyISAM表暂时不支持外键

2) 外键列必须建立了索引,MySQL 4.1.2以后的版本在建立外键时会自动创建索引,但如果在较早的版本则需要显式建立;

3) 外键关系的两个表的列必须是数据类型相似,也就是可以相互转换类型的列,比如int和tinyint可以,而int和char则不可以;

5. 外键的优点
	可以使得两张表关联,保证数据的一致性和实现一些级联操作。保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。使两张表形成关联,外键只能引用外表中的列的值!可以使得两张表关联,保证数据的一致性和实现一些级联操作;

创建外键的语法

1. [CONSTRAINT symbol] foreign key (关联的字段) references 关联的表名(关联的字段);
[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
[ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]

2. 该语法可以在 CREATE TABLE 和 ALTER TABLE 时使用,如果不指定CONSTRAINT symbol,MYSQL会自动生成一个名字。
ON DELETE、 ON UPDATE     # 表示事件触发限制,可设参数

   . cascade方式
在父表上update/delete记录时,同步update/delete掉子表的匹配记录 

   . set null方式
在父表上update/delete记录时,将子表上匹配记录的列设为null
要注意子表的外键列不能为not null  

   . No action方式
如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作  

   . Restrict方式
同no action, 都是立即检查外键约束

   . Set default方式
父表有变更时,子表将外键列设置成一个默认的值 但Innodb不能识别 

示例

1. 表类型必须是 innodb存储引擎,且被关联的字段,即 references指定的另外一个表的字段,必须保证唯一
# 主表
create table t1 (id1 int primary key, name varchar(32) not null)engine=innodb;

2. p_id外键,关联父表(t1主键id1,同步更新,同步删除
# 子表
create table t2 (id int primary key, name varchar(32), p_id int, 
foreign key(p_id)
references t1(id1)
on delete cascade    # 级联删除
on update cascade    # 级联更新
)engine=innodb;

1) 先往父表t1中插入记录
insert into t1 values (1,'教质部'), (2,'技术部'),;

2) 再往子表t2中插入记录
insert into t2 values (1,'yuan',1), (2,'nezha',2), (3,'egon',2), 
(4,'alex',2), (5,'wusir',3), (6,'李沁洋',3),
(7,'皮卡丘',3), (8,'程咬金',3), (9,'程咬银',3);

3) 删父表t1,子表t2中对应的记录跟着删
delete from t1 where id=2;

4) 更新父表t1,子表t2中对应的记录跟着改
update t1 set id=2 where id=3;
posted @ 2019-06-02 21:03  言值  阅读(280)  评论(0编辑  收藏  举报