数据库设计之道:表的巧妙连接与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的索引
相关推荐
WEI_Gaot几秒前
ES6 var + let + const 和 代码块
前端·javascript
dasseinzumtode4 分钟前
在 Vue 3 中实现右键菜单功能
前端·vue.js
精神内耗中的钙奶饼干18 分钟前
Springboot整合kafka记录
后端·kafka
user775742973531521 分钟前
Echarts-Vue3-多图表联动
前端
清弦居士22 分钟前
解锁 Ant Design MCP 组件查询新姿势:大模型组件查询新范式
前端·mcp
JavaGuide22 分钟前
IntelliJ IDEA 2025.1 发布!Java 24 支持、AI 重大更新!!
后端·intellij idea
天天扭码26 分钟前
LeetCode 题解 | 1.两数之和(最优解)
前端·javascript·算法
冉冉同学29 分钟前
【HarmonyOS NEXT】解决微信浏览器无法唤起APP的问题
android·前端·harmonyos
广龙宇32 分钟前
【Web API系列】Web Shared Storage API之WorkletSharedStorage深度解析与实践指南
前端
AronTing36 分钟前
观察者模式:从博客订阅到消息队列的解耦实践
后端·设计模式