1、和外键有关的术语
外键约束、外键字段、外键值。
2、外键约束、外键字段、外键值三者之间关系?
表给某个字段添加外键约束之后,该字段称为外键字段,外键字段中的数据称为外键值。
3、外键的分类(根据字段个数分类)
外键根据个数分为:单一外键、复合外键。
(1)单一外键
单一外键指的是给一个字段添加外键约束。
(2)复合外键
复合外键指的是给多个字段联合添加一个外键。
注意:一张表中可以存在多个外键。
案例一:请设计数据库表来存储员工和部门信息
思路分析:
员工和部门之间的关系:一个员工对应一个部门,一个部门有多个员工,典型的一对多关系。
方案一:将员工信息和部门信息存放在一张表中。
员工表:t_employee
emp_no(PK) |
emp_name |
dept_no |
dept_name |
1 |
tony |
1001 |
开发部 |
2 |
marry |
1002 |
销售部 |
3 |
king |
1002 |
销售部 |
4 |
sack |
1001 |
开发部 |
方案一的缺点是:表中存在数据冗余。
方案二:将员工信息和部门信息分别存放在两张表中。
员工表:t_employee
emp_no(PK) |
emp_name |
dept_no(FK) |
1 |
tony |
1001 |
2 |
marry |
1002 |
3 |
king |
1002 |
4 |
sack |
1001 |
部门表:t_department
dept_no(PK) |
dept_name |
1001 |
development_department |
1002 |
marketing_department |
结论:子表t_employee中的dept_no字段值必须来自父表t_department中的dept_no字段值。
为了保证t_employee表中的dept_no字段中的数据必须来自t_department表中的dept_no字段中数据,有必要给 t_employee表中dept_no字段添加外键约束;dept_no称为外键字段,dept_no中的1001、1002称为外键值,dept_no在这里是单一外键。需要注意以下几点:
(1)外键字段可以为NULL;
(2)被引用字段必须具有unique约束;
(3)有了外键引用之后,表分为父表和子表,以上父表为t_department,子表为t_employee;创建表时先创建父表,再创建子表;删除表时,先删除父表,再删除子表;插入数据时,先插入父表数据,再插入子表数据;删除表中数据时,先删除子表中的数据,再删除父表中的数据。
案例一方式二的实现:
建表语句(先建父表t_department,再建子表t_employee):
create table t_department(
dept_no int(10) primary key,
dept_name varchar(32) not null unique
);
create table t_employee(
emp_noint(10) primary key,
emp_name varchar(32) not null,
dept_no int(10),
constraint fk1 foreign key(dept_no) references t_department(dept_no)
);
插入数据(先插入父表数据,再插入子表数据):
insert into t_department (dept_no,dept_name)
values
(1001,'development_department'),
(1002,'marketing_department');
insert into t_employee(emp_no,emp_name,dept_no)
values
(1,'tony',1001),
(2,'marry',1002),
(3,'king',1002),
(4,'sack',1001);
继续给子表t_employee插入数据
insert into t_employee(emp_no,emp_name,dept_no)
values (5,'winy',1003);
4、级联更新与级联删除
在添加级联更新与级联删除的时候,需要在外键约束后面添加。
注意:级联更新与级联删除操作谨慎使用,因为级联操作会将数据改变或者删除。
级联更新:on update cascade
级联更新的目的:当更新父表中数据的时候,级联更新子表中数据。
第一步:删除子表t_employee中的外键约束
删除外键约束的语法格式:
alter table 子表名 drop foreign key 外键约束名;
首先,查询子表t_employee中的外键约束名
然后,删除子表t_employee中的外键约束
SQL语句:alter table t_employee drop foreign key fk1;
第二步:更新子表t_employee中的外键约束
更新外键约束的语法格式:
alter table 子表名
add constraint 外键约束名 foreign key(子表中外键约束的字段名) references 父表名(父表中被关联字段名)
on update cascade;
SQL语句:
alter table t_employee
add constraint fk1 foreign key(dept_no) references t_department(dept_no)
on update cascade;
第三步:测试级联更新
举例:将父表t_department中部门编号值为1002修改为2001
修改前,先查询父表t_department和子表t_employee
修改后,再查询父表t_department和子表t_employee
级联删除:on delete cascade
级联删除的目的:当删除父表中数据的时候,级联删除子表中数据。
第一步:删除子表t_employee中的外键约束
SQL语句:alter table t_employee drop foreign key fk1;
第二步:更新子表t_employee中的外键约束
SQL语句:
alter table t_employee
add constraint fk1 foreign key(dept_no) references t_department(dept_no)
on delete cascade;
第三步:测试级联更新
举例:删除父表t_department中部门编号为2001的部门
删除前,先查询父表t_department和子表t_employee
删除后,再查询父表t_department和子表t_employee
级联删除和级联更新一起使用
第一步:删除子表t_employee中的外键约束
SQL语句:alter table t_employee drop foreign key fk1;
第二步:更新子表t_employee中的外键约束
SQL语句:
alter table t_employee
add constraint fk1 foreign key(dept_no) references t_department(dept_no)
on delete cascade on update cascade;
10.9 存储引擎
10.9.1 存储引擎介绍
引擎(Engine)是电子平台上开发程序或系统的核心组件。利用引擎,开发者可迅速建立、铺设程序所需的功能,或利用其辅助程序的运转。一般而言,引擎是一个程序或一套系统的支持部分。常见的程序引擎有游戏引擎,搜索引擎,杀毒引擎等。
MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。这些不同的技术以及配套的相关功能在MySQL中被称作存储引擎(也称作表类型)。通过选择不同的技术,你能够获得额外的速度或者功能,从而改善你的应用的整体功能。简单来说,存储引擎就是指表的类型以及表在计算机上的存储方式。
存储引擎的概念是MySQL特有的,其它数据库中没有专门的存储引擎的概念。MySQL提供了插件式(Pluggable)的存储引擎,存储引擎是基于表的,同一个数据库,不同的表,存储引擎可以不同。甚至同一个数据库表,在不同的场合可以应用不同的存储引擎。
存储引擎的本质:不同的存储引擎,底层采用不同的方式来存储数据,MySQL数据管理系统支持很多种。
10.9.2 和存储引擎相关的命令
①命令:show engines; 查看MySQL服务实例支持的存储引擎。
②命令:show create table 表名; 查看某个表用了什么引擎。
注意:MySQL5.5默认的默认的存储引擎是InnoDB。
③命令:set default_storage_engine=MyISAM; 可以“临时地”将MySQL“当前会话的”存储引擎设置为MyISAM。
④命令:show variables like '%storage_engine%'; 可以查看当前MySQL服务实例默认的存储引擎。
10.9.3 和存储引擎相关的文件
在数据库tongying下创建表t_employee时不指定存储引擎,则该表使用的是MySQL指定的默认存储引擎InnoDB。当表t_employee创建后,MySQL服务实例会在数据库目录tongying中自动创建一个名字为表名、后缀名为frm的文件。t_employee.frm(*.frm文件是描述了表的结构)。
举例:创建表emp3,并设置存储引擎为MyISAM。
SQL语句:
use tongying;
create table emp3(
id int(10) primary key,
name varchar(32) not null
)engine=MyISAM;
此时MySQL服务实例会在数据库目录tongying中自动创建3个文件,分别为emp3.frm、emp3.MYD、emp3.MYI
*.frm文件是描述表的结构;*.MYD保存了表的数据记录;*.MYI则是表的索引。
10.9.4 常用的存储引擎
1、InnoDB存储引擎
InnoDB存储引擎是MySQL数据库的默认存储引擎,它管理的表具体有以下特征:
◆每个InnoDB表在数据库目录中以.frm格式文件表示
◆InnoDB表空间tablespace被用于存储表的内容
◆提供一组用来记录事务性活动的日志文件
◆用COMMIT(提交)、SAVEPOINT及ROLLBACK(回滚)支持事务处理
◆提供全ACID(事务的四个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability))兼容
◆在MySQL服务器崩溃后提供自动恢复
◆多版本多版本并发控制(MVCC)和行级锁定
◆支持外键及引用的完整性,包括级联更新和删除
2、MyISAM存储引擎
MyISAM引擎是MySQL数据库最常用的,它管理的表具体以下牲:
◆ 使用三个文件表示每个表:
格式文件 — 存储表的结构(tableName.frm)
数据文件 — 存储表的数据(tableName.MYD)
索引文件 — 存储表的索引(tableName.MYI)
◆ 灵活的AUTO_INCREMENT字段处理
◆ 可被转换为压缩、只读表来节省空间
2、MEMORY存储引擎
使用MEMORY存储引擎的表,其数据存储在内存中,且行的长度固定,这两个特点使得MEMORY存储引擎非常快,MEMORY存储引擎管理的表具有下列特征:
◆ 在数据库目录内,每个表均以.frm格式文件表示
◆ 表数据及索引被存储在内存中
◆ 表级锁机制
◆ 不能包含TEXT或BLOB字段
◆ MEMORY存储引擎以前被称为HEAP引擎
10.9.5 存储引擎的选择
MyISAM表最适合于大量的数据读而少量数据更新的混合操作。MyISAM的优势在于占用空间小,处理速度快。缺点是不支持事务的完整性和并发性。
如果查询中包含较多的数据更新操作,应使用InnoDB。其行级锁机制和多版本的支持为数据读取和更新的混合提供了良好的并发机制。InnoDB的优势在于提供了良好的事务处理、崩溃修复能力和并发控制。缺点是读写效率较差,占用的数据空间相对较大。
可使用MEMORY存储引擎存储非永久需要的数据,或者是能够从基于磁盘的表中重新生成的数据。
在实际工作中,选择一个合适的存储引擎是一个比较复杂的问题。每种存储引擎都有自己的优缺点,不能笼统地说谁比谁好。
存储引擎对比较
特性 |
InnoDB |
MyISAM |
MEMORY |
事务安全 |
支持 |
不支持 |
不支持 |
存储限制 |
64TB |
有 |
有 |
空间使用 |
高 |
低 |
低 |
内存使用 |
高 |
低 |
高 |
插入数据的速度 |
低 |
高 |
高 |
对外键的支持 |
支持 |
不支持 |
不支持 |