数据库设计之道:表的巧妙连接与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的索引
相关推荐
仙俊红几秒前
spring的IoC(控制反转)面试题
java·后端·spring
CheungChunChiu12 分钟前
Linux 内核动态打印机制详解
android·linux·服务器·前端·ubuntu
小楼v12 分钟前
说说常见的限流算法及如何使用Redisson实现多机限流
java·后端·redisson·限流算法
与遨游于天地25 分钟前
NIO的三个组件解决三个问题
java·后端·nio
czlczl200209251 小时前
Guava Cache 原理与实战
java·后端·spring
GIS之路1 小时前
GDAL 创建矢量图层的两种方式
前端
Yuer20252 小时前
什么是 Rust 语境下的“量化算子”——一个工程对象的最小定义
开发语言·后端·rust·edca os·可控ai
小目标一个亿2 小时前
Windows平台Nginx配置web账号密码验证
linux·前端·nginx
短剑重铸之日2 小时前
《7天学会Redis》Day 5 - Redis Cluster集群架构
数据库·redis·后端·缓存·架构·cluster
rocky1912 小时前
网页版时钟
前端·javascript·html