数据库设计之道:表的巧妙连接与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的索引
相关推荐
liangshanbo12159 分钟前
写好 React useEffect 的终极指南
前端·javascript·react.js
earthzhang202139 分钟前
第3讲:Go垃圾回收机制与性能优化
开发语言·jvm·数据结构·后端·性能优化·golang
哆啦A梦15882 小时前
搜索页面布局
前端·vue.js·node.js
_院长大人_3 小时前
el-table-column show-overflow-tooltip 只能显示纯文本,无法渲染 <p> 标签
前端·javascript·vue.js
thinktik3 小时前
AWS EKS 集成Load Balancer Controller 对外暴露互联网可访问API [AWS 中国宁夏区]
后端·kubernetes·aws
追逐时光者3 小时前
将 EasySQLite 解决方案文件格式从 .sln 升级为更简洁的 .slnx
后端·.net
驰羽4 小时前
[GO]GORM 常用 Tag 速查手册
开发语言·后端·golang
哆啦A梦15884 小时前
axios 的二次封装
前端·vue.js·node.js
阿珊和她的猫4 小时前
深入理解与手写发布订阅模式
开发语言·前端·javascript·vue.js·ecmascript·状态模式
yinuo4 小时前
一行 CSS 就能搞定!用 writing-mode 轻松实现文字竖排
前端