数据库 进阶讲解

文章目录

  • 数据库
    • 数据库介绍
      • 数据库三大范式
        • 1NF
        • 2NF
        • 3NF
    • SQL语言
      • 语言分类
      • DDL
        • 建表
      • DML
        • delete 和 truncate
      • DCL
      • DQL
        • 分组查询
          • group by
          • having
    • 数据类型
      • 串数据类型
      • 数值数据类型
      • 日期和时间数据类型
      • 二进制数据类型
    • 数据完整性
    • 多表查询
      • 多表的关系(==重点==)
        • 一对多/多对一(==多塞一==)
        • 多对多(==三张表==)
        • 一对一(==unique==)
      • 多表查询
        • 合并结果集
        • 连接查询(==重点==)
          • 内联查询
          • 外联查询
            • 左外联
            • 右外联
          • 自然连接
        • 子查询(==重点==)
    • 数据库优化
      • SQL 优化
      • (还有其他优化方式,这里暂时不写了)
    • 事务(==重点==)
      • 事务的ACID特性
      • 事务的语法
        • 启动
        • 提交
        • 回滚
        • 演示一下
      • 事务的==并发==问题
        • 脏读
        • 不可重复读
        • 幻读
      • 事务隔离级别
      • 不同隔离级别的锁的情况(了解)
      • 隐式提交(了解)
    • 总结

数据库

这里的所有操作,都以mysql为主

我这里不介绍简单的SQL语句了,但是可以提供简单sql语句的训练题目和答案,如果都练过的话,我相信,简单的 sql 语句将不在话下

数据库介绍

数据库安装,配置什么的就不讲了,网上都有

这里,就介绍一下三大范式

数据库三大范式

1NF

同一数据表,不能出现相同的列名

2NF

每行数据唯一可分(加上一个主键)

3NF

一张表中不包含已经存在的其他表中已包含的非主关键字信息

比如有两张表一张是学生表,一张是学生信息表,如果学生表包含了学生姓名,那学生信息表,就不要包含学生姓名了

SQL语言

语言分类

  • DDL(Data Definition Language):数据定义语言,用来定义数据库对象:库、表、列等。
  • DML(Data Manipulation Language):数据操作语言,用来定义数据库记录(数据)增删改。
  • DCL(Data Control Language):数据控制语言,用来定义访问权限和安全级别。
  • DQL(Data Query Language):数据查询语言,用来查询记录(数据)查询。

倒霉催 Q




我这里给几个简单SQL语句的练习,看了就会了:

# 年级表
drop table if exists `grade`;
create table `grade` (
    `gradeid` bigint not null comment '年级 id',
    `name` varchar(50) comment '年级名称',
    primary key (`gradeid`)
) engine=innodb default charset =utf8mb4 comment '年级表';



# 成绩
drop table if exists `score`;
create table `score` (
    `scoreid` bigint not null comment '成绩id',
    `stuno` bigint not null comment '学员编号',
    `subjectid` bigint not null comment '科目 id',
    `score` int(10) not null comment '分数',
    `examtime` datetime not null comment '考试时间',
    primary key (`scoreid`)
) engine=innodb default charset =utf8mb4 comment '成绩表';


# 学生表
drop table if exists stu;
create table `student` (
    `stuid` bigint not null comment '学生 id',
    `stuname` varchar(50) comment '学生名称',
    `password` varchar(50) comment '登录密码',
    `sex` varchar(10) comment '性别',
    `gid` bigint not null comment '年级id',
    `telphone` varchar(50) comment '电话',
    `address` varchar(255) comment '地址',
    `birthday` date comment '出生日期',
    `email` varchar(50) comment '邮箱',

    primary key (`stuid`)
) engine=innodb default charset =utf8mb4 comment '学生表';





# 科目表
drop table if exists `subject`;
create table `subject` (
    `subjectid` bigint not null comment '科目 id',
    `subjectname` varchar(50) comment '科目名称',
    `studycount` int comment '课时',
    `gradeid` bigint not null comment '年级 id',
    primary key (`subjectid`)
) engine=innodb default charset =utf8mb4 comment '科目表';


-- 1. grade 表增加一个阶段,“就业期”
insert into grade value (1,'就业期');
-- 2.将第三阶段的学生的 gradeid 改为就业期的 id
update stu set gid=(select gradeid from grade where name='就业期') where gid=3;
-- 3.查询所有得了 100 分的学号
select stuno from score where score=100;
-- 4.查询所有 1989 年出生的学生(1989-1-1~1990-1-1)
select * from stu where birthday between '1989-1-1' and '1990-1-1';
-- 5.查询学生姓名为“金蝶”的全部信息
select * from stu where stuname='金蝶';
-- 6.查询 subjectid 为 8 的科目考试未及格(60 分)的学号和成绩
select stuno,score from score where scoreid=8 and score<60;
-- 7.查询第 3 阶段课时大于 50 的课程全部信息
select * from subject where gradeid=3 and studycount>50;
-- 8.查询 S1101001 学生的考试信息
select * from score where stuno='S1101001';
-- 9.查询所有第二阶段的女生信息
select * from stu where gid=2 and sex='女';
-- 10.“基于.NET 平台的软件系统分层开发”需要多少课时
select subjectname,studycount from subject where subjectname='基于.NET 平台的软件系统分层开发';
-- 11.查询“设计 MySchool 数据库”和“面向对象程序设计”的课时(使用 in)
select studycount from subject where subjectname in ('设计 MySchool 数据库','面向对象程序设计');
-- 12 查询所有地址在山东的学生信息
select * from stu where address like '%山东%';
-- 13 查询所有姓凌的单名同学
select * from stu where stuname like '凌%';
-- 14.查询 gradeid 为 1 的学生信息,按出生日期升序排序
select * from stu where gid=1 order by birthday asc;
-- 15.查询 subjectid 为 3 的考试的成绩信息,用降序排序
select * from score where subjectid=3 order by score desc;
-- 16.查询 gradeid 为 2 的课程中课时最多的课程信息
select * from subject where subjectid=2 order by studycount desc limit 0,1;
-- 17.查询北京的学生有多少个
select count(*) from stu where address like '%北京%';
-- 18.查询有多少个科目学时小于 50
select * from subject where studycount<50;
-- 19.查询 gradeid 为 2 的阶段总课时是多少
select sum(studycount) from subject where gradeid=2;
-- 20.查询 subjectid 为 8 的课程学生平均分
select avg(score) from score where subjectid=8;
-- 21.查询 gradeid 为 3 的课程中最多的学时和最少的学时
select max(studycount),min(studycount) from subject where gradeid=3;
-- 22.查询每个科目有多少人次考试
select subjectid,count(*) from score group by subjectid;
-- 23.每个阶段课程的平均课时
select gradeid,avg(studycount) from subject group by gradeid;
-- 24.查询每个阶段的男生和女生个数(group by 两列)
select gid,sex,count(*) from stu group by gid,sex;


BEGIN;
insert into grade values(2,'哈哈');
commit;
rollback;

BEGIN;
insert into grade values(3,'嘿嘿');
rollback;
commit;



-- 雇员表(employee):雇员编号(empid,主键),姓名(name),性别
-- (sex),职称(title),出生日期(birthday),所属部门(depid)
--
--  部门(department):部门编号(depid,主键),部门名称(depname)
--
--  工资表(salary):雇员编号(empid),基本工资(basesalary),职务工
-- 资(titlesalary),扣除(deduction)


# 雇员表
drop table if exists `employee`;
create table `employee` (
    `id` bigint not null comment '雇员编号id',
    `name` varchar(50) comment '姓名',
    `sex` varchar(10) comment '性别',
    `title` varchar(255) comment '职称',
    `birthday` date comment '出生日期',
    `dept_id` bigint comment '所属部门',
    primary key (`id`)
) engine=innodb default charset =utf8mb4 comment '雇员表';


# 部门表
drop table if exists `department`;
create table `department` (
    `id` bigint not null comment 'id',
    `name` varchar(50) comment '部门名称',
    primary key (`id`)
) engine=innodb default charset =utf8mb4 comment '部门表';


# 工资表
--  工资表(salary):雇员编号(empid),基本工资(basesalary),职务工
-- 资(titlesalary),扣除(deduction)
drop table if exists `salary`;
create table `salary` (
    `id` bigint not null comment 'id',
    `emp_id` bigint comment '雇员 id',
    `basesalary` double comment '基本工资',
    `titlesalary` double comment '职务工资',
    `deduction` double comment '扣除',
    primary key (`id`)
) engine=innodb default charset =utf8mb4 comment '工资表';


-- 各表关系为
-- 雇员-部门:多对一
-- 工资-雇员:多对一


# 1. 修改表结构,在部门表中添加部门简介字段
alter table department add column dept_desc varchar(255);

# 2. 将李四的职称改为“工程师”,并将她的基本工资改成 2000,职务工资为 700
update employee,salary
set employee.title='工程师',salary.basesalary=2000
where employee.id = salary.emp_id and employee.name='李四';

# 3. 删除人事部门的部门记录
delete from department where name='人事部门';

# 4. 查询出每个雇员的雇员编号,实发工资,应发工资
select emp_id,basesalary+titlesalary-deduction as '实发工资',basesalary+titlesalary as '应发工资'
from salary;

# 5. 查询姓张且年龄小于 40 的员工记录
select * from employee
where name like '张%'
and DATE_ADD(now(),INTERVAL 40 year )<birthday;

# 6. 查询雇员的雇员编号,姓名,职称,部门名称,实发工资
select employee.id,employee.name,employee.title,department.name,(salary.basesalary+salary.titlesalary-salary.deduction) as '实发工资'
from employee,department,salary
where employee.id=salary.emp_id and employee.dept_id=department.id;

# 7. 查询销售部门的雇员姓名,工资
select employee.name,salary.titlesalary
from department,employee,salary
where employee.id=salary.emp_id and employee.dept_id=department.id and employee.name='销售部门';

# 8. 统计各职称的人数
select title,count(*)
from employee
group by title;

# 9. 统计各部门的部门名称,实发工资总和,平均工资
select department.name,sum(salary.basesalary+salary.titlesalary-salary.deduction) as '实发工资总和',avg(salary.basesalary+salary.titlesalary-salary.deduction) as '实发工资平均'
from department,employee,salary
where employee.id=salary.emp_id and employee.dept_id=department.id
group by department.name;

# 10. 查询比销售部门所有员工基本工资都高的雇员姓名
select employee.name
from employee,salary
where employee.id=salary.emp_id
and salary.titlesalary>(select max(salary.titlesalary)
                        from salary,department,employee
                        where employee.id=salary.emp_id and employee.dept_id=department.id
                        and department.name='销售部门');

DDL

DDL用来建库建表,修改列

建表

这里,我们给出常用的数据类型

数据库 进阶讲解_第1张图片

DML

这里就讲一部分,因为数据库操作和背书差不多

delete 和 truncate

delete: 是删除表数据,后面可以回滚

truncate: 是 drop 整张表,然后创建一个和原来一样的表;数据不能找回,但是比 delete 稍快

DCL

与用户、授权相关

DQL

查询语句

分组查询

group by

当需要分组查询时需要使用GROUP BY子句,例如查询每个部门的工资和,这说明要使用部分来分组。
注意:如果查询语句中有分组操作,则select后面能添加的只能是聚合函数和被分组的列名

为什么需要使用 group by?

假设我们有这么一个需求:查询每个学生的总分

这里我们先介绍一下,每个学生有多个成绩,但是,一个成绩,只对应一个学生,所以是一对多的关系;因为成绩是,所以,成绩表中,有一列,代表的是学生的id

数据库 进阶讲解_第2张图片 数据库 进阶讲解_第3张图片

我们写一下需求的 SQL 语句:

select stu.name,sum(score)
from stu,score
where stu.id = score.stu_id
group by stu.name;

这样就能成功查询到每个学生的成绩总和:

数据库 进阶讲解_第4张图片

这里,如果不使用 group by,那么,数据库没法判断我们要查询的成绩总和是和谁对应,会报错:

select stu.name,sum(score)
from stu,score
where stu.id = score.stu_id;
# group by stu.name;

image-20210507162702402

其实我们想想,逻辑也对不上号,如果不分组,那么查询到的成绩总和,就是所有成绩的总和,也和我们的需求不符,只是数据库发现这个问题,给我们报错了。

having

是在 group by 后,在继续筛选

查询工资总和大于9000的部门编号以及工资和:

SELECT deptno, SUM(sal)
FROM emp
GROUP BY deptno
HAVING SUM(sal) > 9000;

数据类型

这里,整理一下数据库中,所有数据类型

串数据类型

数据库 进阶讲解_第5张图片

数值数据类型

数据库 进阶讲解_第6张图片

日期和时间数据类型

数据库 进阶讲解_第7张图片

二进制数据类型

数据库 进阶讲解_第8张图片

数据完整性

用来保证存放到数据库中的数据是有效的,即数据的有效性和准确性 确保数据的完整性 = 在创建表时给表中添加约束
完整性的分类:

  • 实体完整性(行完整性)
    • 主键约束:primary key:每个表有一个主键
    • 唯一约束:unique [key]:数据不能重复
    • 自动增长:auto_increment :主键自增长
  • 域完整性(列完整性)
    • 非空约束:not null:数据不能为空
    • 默认约束:default :为属性设置默认值
  • 引用完整性(关联表完整性)
    • 外键约束: foreign key:

建议这些约束应该在创建表的时候设置

多个约束条件之间使用空格间隔

示例:

create table student(
  studentno int primary key auto_increment, loginPwd varchar(20) not null default '123456', studentname varchar(50) not null,
  sex char(2) not null,
  gradeid int not null,
  phone varchar(255) not null,
  address varchar(255) default '学生宿舍', borndate datetime,
  email varchar(50)
);

多表查询

多表的关系(重点

不要小瞧这个知识点,只有掌握了这些关系,才能设计更好的表关系

一对多/多对一(多塞一)

客户和订单,分类和商品,部门和员工

多方塞入一方的 id

数据库 进阶讲解_第9张图片

多对多(三张表

学生和课程,学生上多个课程,一个课程,也包含多个学生

需要三张表,才能表示此关系

学生表和课程表,必须借助第三个表 学生_课程表,才能表示多对多关系

数据库 进阶讲解_第10张图片

一对一(unique

一夫一妻

将引用的对方非 id,都设为 unique

数据库 进阶讲解_第11张图片

多表查询

多表查询分为下面这些:

  1. 合并结果集:UNION 、 UNION ALL
  2. 连接查询(
    1. 内连接 [INNER] JOIN ON
    2. 外连接 OUTER JOIN ON
    3. 左外连接 LEFT [OUTER] JOIN
    4. 右外连接 RIGHT [OUTER] JOIN
    5. 全外连接(MySQL不支持)FULL JOIN
    6. 自然连接 NATURAL JOIN
  3. 子查询(

合并结果集

数据库 进阶讲解_第12张图片

连接查询(重点

连接查询,就是查出两张表的笛卡尔积

数据库 进阶讲解_第13张图片

我们在继续往下面讲之前,先建几个表,并插入测试数据

CREATE TABLE dept1(
deptno int primary key,
dname  varchar(14),
loc  varchar(13)
);
insert into dept1 values(10,'服务部','北京'); 
insert into dept1 values(20,'研发部','北京'); 
insert into dept1 values(30,'销售部','北京'); 
insert into dept1 values(40,'主管部','北京'); 



CREATE TABLE emp1(
    empno        int,
    ename        varchar(50),
    job        varchar(50),
    mgr        int,
    hiredate    date,
    sal          double,
    comm           double,
		depton						int
 );
insert into emp1 values(1001,'张三','文员',1006,'2019-1-1',1000,2010,10);
insert into emp1 values(1002,'李四','程序员',1006,'2019-2-1',1100,2000,20); 
insert into emp1 values(1003,'王五','程序员',1006,'2019-3-1',1020,2011,20); 
insert into emp1 values(1004,'赵六','销售',1006,'2019-4-1',1010,2002,30); 
insert into emp1 values(1005,'张猛','销售',1006,'2019-5-1',1001,2003,30); 
insert into emp1 values(1006,'谢娜','主管',1006,'2019-6-1',1011,2004,40);

如果没有表1.列名=表2.列名,那查出的笛卡尔积,是没有意义的,我们要在笛卡尔积中,找出又用信息。因为这个表的设计,是按照 一 对多来的,所以,我们只要指定找出的笛卡尔积中,多的一方引用的一的一方的 id,等于一的一方的 id,就能找出有关联关系的数据

比如说,我们想查找每个员工,各处在什么部门:

select emp1.ename,dept1.dname from emp1,dept1 where emp1.depton=dept1.deptno;
数据库 进阶讲解_第14张图片
内联查询

我们的一对多/多对一 或者一对一的查询,都需要用到两张表的内联查询

我们的多对对,就需要用到三张表的内联查询

select 列名
from1
inner join2
on1.列名=2.列名 //外键列的关系 where.....

等价于:

如果没有表1.列名=表2.列名,那查出的笛卡尔积,是没有意义的,我们要在笛卡尔积中,找出又用信息。因为这个表的设计,是按照 一 对多来的,所以,我们只要指定找出的笛卡尔积中,多的一方引用的一的一方的 id,等于一的一方的 id,就能找出有关联关系的数据

select 列名
from1,2
where1.列名=2.列名 and ...(其他条件)

拿我们插入的数据举例,比如说,我们想查找每个员工,各处在什么部门:

连接查询:

select emp1.ename,dept1.dname from emp1,dept1 where emp1.depton=dept1.deptno;
数据库 进阶讲解_第15张图片

内联查询:

与上面的写法等价

select emp1.ename,dept1.dname
from emp1
inner join dept1
on emp1.depton=dept1.deptno;
数据库 进阶讲解_第16张图片

三表联查:

对于多对多关系,需要用到三标联查,我们的操作还是差不多

假设我们有 stu teacher stu_teacher 表 (学生有多个老师,老师也有多个学生,所以是多对多,所以要三张表)

我们的业务需求,是查询每位学生的所有老师

使用一般连接查询:

select stu.name,teacher.name
from stu,teacher,stu_teacher
where stu.id=stu_teacher.stu_id and teacher.id=stu_teacher.teacher_id

使用内联查询:

select stu.name,teacher.name
from stu
inner join stu_teacher on stu.id = stu_teacher.stu_id
inner join teacher on stu_teacher.teacher_id = teacher.id
外联查询
左外联

– 左外联:select 列名 from 主表 left join 次表 on 主表.列名=次表.列名

– 1.主表数据全部显示,次表数据匹配显示,能匹配到的显示数据,匹配不成功的显示null

– 2.主表和次表不能随意调换位置

除了将 inner join 换成 left join,其他写法和内联查询一样,但是其可以显示没有连接关系的数据,并把空数据显示出来

右外联

就是把左外联换个方向

自然连接

自然连接(NATURAL INNER JOIN):自然连接是一种特殊的等值连接,他要求两个关系表中进行连 接的必须是相同的属性列(名字相同),无须添加连接条件,并且在结果中消除重复的属性列。

子查询(重点

就是查询套查询

子查询出现的位置:

  1. where后,作为条为被查询的一条件的一部分;
  2. from后,作表(因为查询语句,最最后查出来的,就是一张虚拟表,我们当然可以对这张虚拟表进行操作)

数据库优化

SQL 优化

  1. 对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引 (即使用主键)
  2. 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫
    描,如:
select id from t where num is null

最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库.
备注、描述、评论之类的可以设置为 NULL,其他的,最好不要使用NULL。

  1. 应尽量避免在 where 子句中使用 != 或 <> 操作符,否则引擎将放弃使用索引而进行全表扫描。
  2. 应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致 引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or Name = 'admin'

可以这样查询:

select id from t where num = 10
union all
select id from t where Name = 'admin'
  1. in 和 not in 也要慎用,否则会导致全表扫描,如:select id from t where num in(1,2,3)
    对于连续的数值,能用 between 就不要用 in 了: select id from t where num between 1 and 3
    很多时候用 exists 代替 in 是一个好的选择

(还有其他优化方式,这里暂时不写了)

事务(重点

事务的ACID特性

  1. 原子性(Atomicity) :

    要么全部成功,要么全部失败

    事务的原子性是指事务必须是一个原子的操作序列单元。事务中包含的各项操作在一次执行过程中,只 允许出现两种状态之一。
    **(1)**全部执行成功
    **(2)**全部执行失败 事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错, 会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就 像化学中学过的原子,是物质构成的基本单位。

  2. 一致性(Consistency):

    宇宙的总量是不变的

    事务的一致性是指事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处以一致性状态。
    比如:如果从A账户转账到B账户,不可能因为A账户扣了钱,而B账户没有加钱。

  3. 隔离性(Isolation):

    并发的事务,不能相互干扰

    事务的隔离性是指在并发环境中,并发的事务是互相隔离的。也就是说,不同的事务并发操作相同的数 据时,每个事务都有各自完整的数据空间。 一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务是不能互相干扰的。 隔离性分4个级别,下面会介绍。

  4. 持久性(Duration):

    事务一旦提交,就会永久保存这个数据

    事务的持久性是指事务一旦提交后,数据库中的数据必须被永久的保存下来。即使服务器系统崩溃或服 务器宕机等故障。只要数据库重新启动,那么一定能够将其恢复到事务成功结束后的状态

事务的语法

注意,只有 InnoDB 引擎支持,其他类型不支持事务

启动

start transactionbegin

提交

commit

回滚

rollback

==注意:==回滚操作,必须在事务提交之前,才能生效;如果 commit 了,就不能回滚了!

演示一下

下面,我们就来演示一下事务的操作

这里,我们操作 grade 表:

数据库 进阶讲解_第17张图片

我们用 BEGIN 开启事务操作,然后执行插入:

BEGIN;
insert into grade values(2,'哈哈');

可以看到,这个时候,数据库中的内容是没有更新的:

数据库 进阶讲解_第18张图片

我们再执行 commit 操作:

# BEGIN;
# insert into grade values(2,'哈哈');
commit;  # 执行 commit

这时候,我们发现,数据库持久成更新了:

数据库 进阶讲解_第19张图片

我们在事务提交后,想再执行回滚,已经没用了:

# BEGIN;
# insert into grade values(2,'哈哈');
# commit;
rollback; # 提交后,再回滚,已经无济于事了

但是,如果在提交前回滚,就 ok:

数据库 进阶讲解_第20张图片

数据库 进阶讲解_第21张图片

事务的并发问题

脏读

读取到了没有提交的数据, 事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的 数据是脏数

数据库 进阶讲解_第22张图片

不可重复读

同一条命令返回不同的结果集(更新).事务 A 多次读取同一数据,事务 B 在事务A 多次读取的 过程中,对数据做了更新并提交,导致事务A多次读取同一数据时,结果不一致

数据库 进阶讲解_第23张图片

幻读

重复查询的过程中,数据 就发生了量的变化(insert, delete)

幻读和不可重复读很像,但是,幻读是发生了量的变化(insert,delete),不可重复读是发生了更新操作

数据库 进阶讲解_第24张图片

事务隔离级别

事务隔离级别,可以用来解决事务的并发问题

数据库 进阶讲解_第25张图片

4种事务隔离级别从上往下,级别越高,并发性越差,安全性就越来越高。

一般数据默认级别是 读以提交或可重复读

不同隔离级别的锁的情况(了解)

  1. 读未提交(RU): 有行级的锁,没有间隙锁。它与RC的区别是能够查询到未提交的数据。
  2. 读已提交(RC):有行级的锁,没有间隙锁,读不到没有提交的数据。
  3. 可重复读(RR):有行级的锁,也有间隙锁,每次读取的数据都是一样的,并且没有幻读的情况。
  4. 序列化(S):有行级锁,也有间隙锁,读表的时候,就已经上锁了

隐式提交(了解)

DQL:查询语句

DML:写操作(添加,删除,修改)

DDL:定义语句(建库,建表,修改表,索引操作,存储过程,视图)

DCL: 控制语言(给用户授权,或删除授权)

DDL(Data Define Language):都是隐式提交。 隐式提交:执行行行这 种语句相当于执行commit;

总结

  • 三大范式

1nf:同一张表,不能有相同的列

2nf:每张表的行唯一(加主键)

3nf:引用其他表,只能引用其他表的主键(不能使用其他表的其他属性)

  • SQL 语句

DDL,DML,DCL,DQL (DMCQ 倒霉催 Q)

  • 数据完整性
  • 实体完整性(行完整性)
    • 主键约束:primary key:每个表有一个主键
    • 唯一约束:unique [key]:数据不能重复
    • 自动增长:auto_increment :主键自增长
  • 域完整性(列完整性)
    • 非空约束:not null:数据不能为空
    • 默认约束:default :为属性设置默认值
  • 引用完整性(关联表完整性)
    • 外键约束: foreign key:
  • 多表关系(表设计的重要知识!!)

一对多/多对一:多包一

多对多:三张表

一对一:unique

  • 多表查询

内联:

查询多张有关系的表

一对多/多对一关系想表,要两张表联查

多对多关系的表,要三张表联查

外联:

查询两张表,一方全部显示,另一方和这一方面有关联,显示,没关联,显示 null

左外联,左边是主表,右边是副表

右外联,左边是副表,右边是主表

自然连接:

自然连接(NATURAL INNER JOIN):自然连接是一种特殊的等值连接,他要求两个关系表中进行连 接的必须是相同的属性列(名字相同),无须添加连接条件,并且在结果中消除重复的属性列。

  • 事务

数据库 进阶讲解_第26张图片

你可能感兴趣的:(数据库,mysql,数据库)