数据库设计之道:表的巧妙连接与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的索引
相关推荐
|晴 天|7 小时前
Vue 3 + TypeScript + Element Plus 博客系统开发总结与思考
前端·vue.js·typescript
猫3287 小时前
v-cloak
前端·javascript·vue.js
旷世奇才李先生8 小时前
Vue 3\+Vite\+Pinia实战:企业级前端项目架构设计
前端·javascript·vue.js
GetcharZp8 小时前
比 Zap 还要快?Go 社区高性能日志神器 Zerolog 落地实践指南
后端
anzhxu8 小时前
Go基础之环境搭建
开发语言·后端·golang
刀法如飞9 小时前
一款Python语言Django框架DDD脚手架,适合中大型项目
后端·python·领域驱动设计
zb200641209 小时前
SpringBoot详解
java·spring boot·后端
SoaringHeart9 小时前
Flutter进阶:用OverlayEntry 实现所有弹窗效果
前端·flutter
AI人工智能+电脑小能手10 小时前
【大白话说Java面试题】【Java基础篇】第7题:HashMap的get流程是什么
java·后端·面试·哈希算法·散列表·hash-index·hash
霸道流氓气质11 小时前
SpringBoot+LangChain4j+Ollama+RAG(检索增强生成)实现私有文档向量化检索回答
java·spring boot·后端