数据库设计之道:表的巧妙连接与MySQL实用技巧

上节课我们学习了设计数据库的三大范式,主要研究的是把表拆开,那么我们再把表拆开之后,有的时候需要把表合并起来,这节课我们就来探讨一下如何将表合并起来。

  1. JOIN连接表,主要有以下几种
  • inner join
  • left join
  • right join
  • full outer join
  • 我们可以通过下图去理解记忆
  1. 制造一些数据
  • 启动mysql,docker container start mysql1
  • 进入mysql
    • docker exec -it mysql1 bash
    • mysql -u root -p123456
  • 创建数据库,之后
sql 复制代码
CREATE DATABASE db1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
use databases;
use db1;
  • 创建表
arduino 复制代码
create table users(id serial,name text);
  • 创建数据库,以下创建的三个表描述的是超市员工买东西给用户的场景
sql 复制代码
create table users(id serial,name text);
show tables;
create table staffs(id serial,name text);
show tables;
create table orders(id serial,user_id bigint unsigned,staff_id bigint unsigned,amount int unsigned);
show tables;
  • 创建一些数据
sql 复制代码
insert into users (name) values ('XiaoMing');
select * from users;
insert into staffs (name) values ('XiaoHong');
select * from staffs;
insert into orders (user_id,staff_id,amount) values (1,1,100);
select * from orders;
  1. 开始尝试join命令
  • 如何得到XiaoMing 购买了100,使用inner join
sql 复制代码
select users.name, orders.amount from users inner join orders on users.id = orders.user_id;
+----------+--------+
| name     | amount |
+----------+--------+
| XiaoMing |    100 |
+----------+--------+
  • 在users表中再插入一条数据,尝试使用left join会保留右边的null, 以保证左边的信息显示全
sql 复制代码
insert into users (name) values ('LiBai');
select users.name, orders.amount 
from users left join orders 
on users.id = orders.user_id;
+----------+--------+
| name     | amount |
+----------+--------+
| XiaoMing |    100 |
| LiBai    |   NULL |
+----------+--------+
  • 使用right join,左还是右主要是看orders right join users 这一句,会保留左边的null,保证右边都显示
sql 复制代码
select users.name, orders.amount from 
orders right join users 
on users.id = orders.user_id;
+----------+--------+
| name     | amount |
+----------+--------+
| XiaoMing |    100 |
| LiBai    |   NULL |
+----------+--------+
  • full outer join一般是多对多才会有,保证两边都显示,这里是一对多所以无法演示,
  • 别名as语法的使用
sql 复制代码
select users.name as uname, orders.amount as oamount
from users inner join orders 
on users.id = orders.user_id;
+----------+---------+
| uname    | oamount |
+----------+---------+
| XiaoMing |     100 |
+----------+---------+
  1. mysql常用技巧
  • 缓存字段

    • 假设一个博客blog包含多个评论comments
    • 如何获取博客的评论数
      • select count(id) from comments where blog_id=8
      • 这样太慢了,可不可以在blog表上加一个comment_count字段
      • 可以每次添加comment则+1,每次删除comment则-1
      • 所有这些操作都以_count作为结尾
  • 事务

    • 有些操作必须一次完成
      • 用户评论之后,要做两件事情
      • 第一步,在comments表新增记录
      • 第二步,在blogs表将对应的comment_count+1
      • 如果第一步执行了,第二步没有执行,数据就乱了
    • 使用事务
      • 只要有一句出错,则全都不生效。
ini 复制代码
start transaction;
语句1;语句2;语句3;
commit;
  • MySQL存储引擎

    • 命令`SHOW ENGINES``;
    • 常见的存储引擎
      • InnoDB-默认,目前版本是新版InnoDB
      • MyISAM-拥有较高的插入、查询速度,但不支持事务
      • Memory-内存中,快速访问数据
      • Archive-只支持insert和select
    • InnoDB
      • InnoDB是事务型数据库的首选,支持事务、遵循ACID、支持行锁和外键
  • 索引

    • 语法
scss 复制代码
CREATE UNIQUE INDEX index1 ON users(name(100)) // 100是索引的长度,默认长度不超过字段的长度
show index in users;
  • 用途,提交搜索效率
    • where xxx>100那么我们可以创建xxx的索引
    • where xxx>l00 and yyy>200,创建xxx,yyy的索引
相关推荐
歪歪1001 分钟前
如何配置Webpack以实现按需加载模块?
开发语言·前端·webpack·node.js
面向星辰3 小时前
html各种常用标签
前端·javascript·html
梦6503 小时前
HTML新属性
前端
东风西巷5 小时前
PDFgear:免费全能的PDF处理工具
前端·pdf·软件需求
小沈同学呀5 小时前
创建一个Spring Boot Starter风格的Basic认证SDK
java·spring boot·后端
森之鸟5 小时前
Mac电脑上如何打印出字体图标
前端·javascript·macos
mCell6 小时前
GSAP 入门指南
前端·javascript·动效
gnip6 小时前
组件循环引用依赖问题处理
前端·javascript
方圆想当图灵7 小时前
如何让百万 QPS 下的服务更高效?
分布式·后端
凤山老林7 小时前
SpringBoot 轻量级一站式日志可视化与JVM监控
jvm·spring boot·后端