1
2
3
4
5
6
7
8
启动 mysql
docker container start mysql1
或者
docker run --name mysql1 -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql:5.7.27
进入 mysql
docker exec -it mysql1 bash
mysql -u root -p
输入密码 123456

第一范式

- 定义
  1. 字段不可再分
- 举例
  1. 我们要储存体检者的双眼视力
  2. 那么我们应该存为左眼视力和右眼视力两个字段
  3. 即 user 表里应该有 left_eye 和 right_eye
  4. 而不能把他们存在一个字段里

缺点:

这是一个学生选课表,没有违反第一范式,但是存在如下问题:
数据冗余、创建系时插入异常。删除学生会导致系消失、学生改系时改动多处

结论:第一范式不够强大。

第二范式

- 定义(不标准)
  1. 在 1NF 的基础上,要有键(键可由多个字段组合)
  2. 所有字段分别 完全依赖 于键
  3. 如果键是多个字段组合,则不允许部分依赖于该键
- 依赖关系
  1. 给出键,就能唯一确定字段的值,
  2. 如果给出学号,就能唯一确定姓名,反之则不行
  3. 则称姓名依赖于学号
不满足第二范式的地方
  1. 上表的键为(学号,课名)
  2. 但存在部分依赖:姓名依赖于学号
改进
  1. 选课表(学号,课名,分数)
  2. 学生表(学号,姓名,系名,系主任)

第三范式

- 定义(不标准)
  1. 一个表里不能有两层依赖
  2. 给出学号,就能确定系名:系名依赖学号
  3. 给出系名,就能确定系主任:系主任依赖于系名
  4. 所以,系主任间接依赖于学号
改进
  1. 把系名和系主任单独建表

总结

  • 第一范式
    属性不可分割
  • 第二范式
    字段完全依赖于键
  • 第三范式
    字段没有间接依赖
  • BC 范式
    键中的属性也不存在间接依赖

JOIN

  1. inner join
  2. left join(会保留右边的 null,以保证左边都显示)
  3. right join(会保留左边的 null,以保证右边都显示)
  4. full outer join(保留两边的 null,以保证两边都显示)

语法:

公式:SELECT A.PK,B.PK,A.Value,b.Value
FROM Table_A
INNER JOIN Table_B
ON A.PK = B.PK;

栗子: select usesr.name , orders.amount from users inner join orders
on users.id = orders.userId;

三张表

查询结果

其他技巧

缓存字段

假设一个博客 blog 包涵多个评论,现在想知道有多少条评论
使用 count 太慢了
我们可以在 blog 表中增加字段 commemt_count
每次增加一条评论就给 comment_count 加1
每次删除一条评论就给 comment_count 减1

事务

有些操作必须一次完成
还是上述栗子,用户评论完我们要做两件事情
第一步在 comment 表中增加一条数据
第二部在 blog 表中给 comment_count 加1
但是 如果第一步执行了,第二步没有执行怎么办(比如网络波动之类的一些其他事故)
那么数据就乱了
所以我们需要使用事务,两个操作一起成功,如果有一个失败,那么就不生效。

MySQL 储存引擎

命令:SHOW ENGINES;

  • 常见的
  1. InnoDB - 默认,目前版本是新版 InnoDB
  2. MyISAM - 拥有较高的插入、查询速度,但不支持事务
  3. Memory - 内存中,快速访问数据
  4. Archive - 只支持 insert 和 select

InnoDB 是事务型数据库的首选,支持事务、遵循 ACID、支持行锁和外键

索引

  1. 提高搜索效率
  2. where xxx > 100 那么我们就可以创建 xxx 的索引
  3. where xxx > 100 and yyy > 200,创建xxx,yyy的索引