一文整理完MySQL关系型数据库相关知识

MySQL关系型数据库

    • 1. 介绍
      • 1.1 MySQL
    • 2. 安装
    • 3. SQL语句
    • 4. SQL分类
    • 5. DDL
      • 5.1 库的DDL
      • 5.2 表、列的DDL
    • 6. DML
      • 6.1 添加数据
      • 6.2 修改数据
      • 6.3 删除数据
    • 7. DQL
      • 7.1 基础查询
      • 7.2 条件查询
      • 7.3 排序查询
      • 7.4 聚合函数
      • 7.5 分组查询
      • 7.6 分页查询
    • 8. 约束
      • 8.1 约束分类
    • 9. 多表查询
      • 9.1 内连接查询
      • 9.2 外连接查询
      • 9.3 子查询
    • 10. 事务
      • 10.1 隔离级别
    • 11. 函数
      • 11.1 数学函数
      • 11.2 字符串函数
      • 11.3 日期函数
    • 12. DCL
      • 12.1 用户管理
      • 12.2 权限管理
    • 13. 备份与还原
    • 14. 表设计流程
      • 14.1 三级模式和两级映射
      • 14.2 数据库设计过程
      • 14.3 需求说明和数据字典
      • 14.4 E-R模型
      • 14.5 关系模式
    • 15. 规范化理论
      • 15.1 范式
      • 15.2 反范式
    • 16. 并发控制
    • 17. 优化
      • 17.1 SQL及索引
      • 17.2 数据库结构优化
      • 17.3 系统配置优化
        • 17.3.1 操作系统配置优化
        • 17.3.2 MySQL配置文件
      • 17.4 服务器硬件优化

1. 介绍

在这里插入图片描述

在开发中,数据库是专门用来存取数据的软件。数据库的职责就是管理数据的。

根据存取数据的类型分为关系型数据库和非关系型数据库
在这里插入图片描述

数据存储后呈现出来的效果类似上图的,是关系型数据库

在这里插入图片描述

数据存储后呈现出来的效果类似上图的,是非关系型数据库

1.1 MySQL

在这里插入图片描述

官网:http://www.mysql.com

2. 安装

docker方式安装MySQL数据库

前提:安装好了docker软件

1、拉取MySQL镜像

docker pull mysql:5.7   # 拉取 mysql 5.7
docker pull mysql       # 拉取最新版mysql镜像

2、docker run镜像创建容器

docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql:5.7
  • –name:容器名,此处命名为mysql
  • -e:配置信息,此处配置mysql的root用户的登陆密码
  • -p:端口映射,此处映射容器的3306端口主机3306端口
  • -d:后台运行容器,保证在退出终端后容器继续运行

设置MySQL挂载目录,启动MySQL容器操作步骤

# MySQL挂在目录创建
mkdir -p /home/mysql/{conf,data,log,mysql-files}

# 新建配置文件
vim /home/mysql/conf/my.cnf

# 配置文件如下:
[client]
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4

[mysqld]

character-set-server=utf8
collation-server=utf8_general_ci
lower_case_table_names=1
init_connect='SET NAMES utf8'
max_connections=5000
wait_timeout=20000
max_user_connections=5000
max_allowed_packet=128M
thread_stack=262144

# 容器启动命令
docker run --restart=always --privileged=true --name mysql-container \
-v /home/mysql/conf:/etc/mysql/conf.d \
-v /home/mysql/data:/var/lib/mysql \
-v /home/mysql/log:/var/log \
-v /home/mysql/mysql-files:/var/lib/mysql-files \
-p 3306:3306 -e MYSQL_ROOT_PASSWORD='123456' -id mysql:latest

在这里插入图片描述

3. SQL语句

SQL的英文是Structured Query Language,简称SQL,是一种操作关系型数据库的结构化查询语言。操作数据库,最经常使用就是查询操作。

1、MySQL数据库的SQL语句不区分大小写,关键字建议使用大写;

2、SQL语句可以使用单行或多行书写,以分号结尾

3、注释

单行注释

- 单行注释

# 单行注释

多行注释

/*
多行注释
多行注释
*/

4. SQL分类

分类说明作用备注
DDL数据定义语言用来对数据库、表、列的定义data definition language
DML数据操作语言用来对数据库中表的数据进行增、删、改操作data manipulation language
DQL数据查询语言用来对数据库中表的数据进行查询data query language
DCL数据控制语言用来对数据库的控制(用户创建、权限控制)data control language

5. DDL

5.1 库的DDL

展示所有的数据库

show databases;

创建数据库

create database 数据库名称 charset=utf8;
create database if not exists 数据库名称 charset=utf8;

示例:

create database db1 charset=utf8;
create database if not exists db1 charset=utf8;

删除数据库

drop database 数据库名称;
drop database if exists 数据库名称;

示例:

drop database test;
drop database if exists test;

使用数据库

use 数据库名称;

查询正在使用的数据库

select database();

小结:

命令作用示例
show databases;查看所有数据库show databases;
create database if not exists 数据库名 charset=utf8;创建数据库create database if not exists db1 charset=utf8;
use 数据库名;使用数据库use db1;
select database();查看当前使用的数据库select database();
drop database if exists 数据库名;删除数据库drop database if exists db1;

5.2 表、列的DDL

列的内容可以是数字、字符串、时间等,由数据类型约束

数值数据类型

数据类型字节数有符号无符号
tinyint1个字节-128~1270~255
smallint2个字节-32768~327670~65535
mediumint3个字节-8388608~83886070~16777215
int4个字节-2147483648~21474836470~4294967295
bigint8个字节-263~263-10~2^64-1
float单精度,4个字节-231~231-10~2^32-1
double双精度,8个字节
decimal[M, D]双精度,8个字节

decimal(5,2),表示共5位数字,其中2位是小数,比如:888.88

字符串数据类型

数据类型长度用途
char(size)最大255个字符数据是定长,如md5的密码,邮编,手机号,身份证号等
varchar(size)最大65535个字节存放一般内容长度
tinytext最大255个字节
text最大65535个字节
mediumtext最大16777215个字节大段文本时,如新闻、文章、论文等
longtext最大4294967295个字节大段文本时,如新闻、文章、论文等

1、VARCHAR(size):0~65535字节 可变长度字符串,最大65532字节,1-3个字节用于记录大小【utf8编码size最大21844字符,gbk编码最大32766字符 】

2、查询速度:char > varchar

3、text与char、varchar不同的是,text不可以有默认值,能用varchar的地方不用text

日期+时间数据类型

数据类型格式
date年-月-日,如:2024-4-8
datetime年-月-日 时:分:秒,如:2024-4-8 16:17:40
timestamp年-月-日 时:分:秒,如:2024-4-8 16:17:40
time时:分:秒,如:16:17:40
year年,如:2024

datetime保存时间的范围: 1000-01-01 00:00:009999-12-31 23:59:59

timestamp保存时间的范围: 1970-01-01 00:00:012038-01-19 03:14:07

展示当前数据库所有表

show tables;

描述表结构

desc 表名;

查看表的创建语句

show create table 表名;

创建表

create table 表名(
		字段名1 数据类型,
		字段名2 数据类型,
		...
		字段名n 数据类型  # 最后一个不需要逗号(,)
);

删除表

drop table 表名称;
drop table if exists 表名称;

修改表、列

# 修改表名
alter table 表名 rename to 新的表名;

# 增加一列
alter table 表名 add 列名 数据类型;

# 修改列数据类型
alter table 表名 modify 列名 新数据类型;

# 修改列名和数据类型
alter table 表名 change 列名 新列名 新数据类型;

# 删除列
alter table 表名 drop 列名;

小结:

命令作用
show tables;查看当前数据库中所有表
desc 表名;查看表结构
show create table 表名;查看表的创建语句
alter table 表名 rename to 新的表名;修改表名
alter table 表名 add 列名 类型;添加字段
alter table 表名 modify 列名 类型及约束;修改字段数据类型
alter table 表名 change 原名 新名 类型及约束;修改字段名和数据类型
alter table 表名 drop 列名;删除字段
drop table 表名;删除表

6. DML

6.1 添加数据

添加指定列数据

insert into 表名(列名1,列名2...) values(1,2...);

添加全部列数据

insert into 表名 values(1,2...);

批量添加指定列数据

insert into 表名(列名1,列名2...) values(1,2...),(1,2...)...;

批量添加全部列数据

insert into 表名 values(1,2...),(1,2...)...;

6.2 修改数据

修改表数据

update 表名 set 列名1=1 列名2=2...[where条件];

注:如果不加where条件,就是对该表所有行内容进行修改

6.3 删除数据

删除表数据

delete from 表名 [where条件]

注:如果不加where条件,就是对该表所有行内容进行删除

7. DQL

完整语法

SELECT
	字段列表
FROM
	表名列表
WHERE
	条件列表
GROUP BY
	分组字段
HAVING
	分组后条件
ORDER BY
	排序字段
LIMIT
	分页限定
- 创建数据库
create database if not exists db1

- 创建数据库表
use db1;

create table if not exists stu(
	id int(11),
    username varchar(32),
    sex tinyint(1),
    age tinyint(3),
    math tinyint(3),
    chinese tinyint(3)
);

- 添加数据
insert into stu values(1,'小张',1,16,75,86),(2,'小李',1,16,76,86),(3,'小王',0,17,76,87),(4,'小胡',0,17,77,87),(5,'小丘',0,18,77,88),(6,'小刘',0,18,80,90);

7.1 基础查询

- 查询指定字段
select id,username from stu;

- 查询表所有字段
select * from stu;

- 去除重复记录
select distinct sex from stu;

- 字段取别名
select id,sex as gender,math shuxue from stu;

7.2 条件查询

select 字段列表 from 表名 where条件

where后面支持多种运算符

运算符功能描述
比较运算符=、>、>=、<、<=、!=、<>
逻辑运算符and、&&、or、||、not
模糊查询like
范围查询between…and…、in(…)
空判断is null、is not null

模糊查询使用like关键字,可以使用通配符进行占位

_:代表单个任意字符

%:代表任意个字符

正则表达式

select * from stu where class_id REGEXP '1|7';

7.3 排序查询

select 字段列表 from 表名 order by 排序字段名1 [,排序字段2]...;

注:排序方式有上序ASC,降序DESC,默认情况下是升序ASC

select * from stu order by math desc,chinese desc;

7.4 聚合函数

在进行查询操作时,往往需要对一整列进行运算,例如成绩的平均分

函数名功能
count(列名)统计数量(一般选用不为null的列)
max(列名)最大值
min(列名)最小值
sum(列名)求和
avg(列名)平均值
select 聚合函数 from 表名;

注:NULL值不参与聚合函数运算

7.5 分组查询

select 字段列表 from 表名 [where分组前的条件限定] group by 分组字段名 [having 分组后的条件过滤];

注:分组之后,查询的字段为聚合函数和分组字段,查询其他字段无任何意义

select sex,max(math),max(chinese) from stu group by sex;

7.6 分页查询

select 字段列表 from 表名 limit 查询起始索引,查询条目数

注:limit关键字中,查询起始索引是从0开始的

8. 约束

约束是作用于数据库表中列上的规则,用于限制添加数据的行为。从而保证数据库中数据的正确性、有效性和完整性。

8.1 约束分类

约束类型关键字功能
非空约束NOT NULL保证列中所有数据不能有NULL值
唯一约束UNIQUE保证列中所有数据各不相同
主键约束PRIMARY KEY主键是一行数据的唯一标识,要求非空且唯一
默认约束DEFAULT保存数据时,未指定值则采用默认值
外键约束FOREIGN KEY外键用来让两个表数据建立关联,保证数据的一致性和完整性
检查约束CHECK保证列中的值满足某一条件
create table if not exists stu(
	id int(11) unsigned auto_increment primary key not null,
    username varchar(32) not null unique,
    sex tinyint(1) default 1 not null,
    age tinyint(3) not null,
    math tinyint(3) default 0 not null,
    chinese tinyint(3) default 0 not null
);

9. 多表查询

一次性从多张表中查询需要的数据

create table class(
	class_id int(11) unsigned auto_increment primary key not null,
    class_name varchar(32) not null unique
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=UTF8;

create table stu(
	stu_id int(11) unsigned auto_increment primary key not null,
    class_id int(11) not null,
    stu_name varchar(32) not null unique
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=UTF8;

insert into class(class_name) values('一班'),('二班');

insert into stu(class_id,stu_name) values(1,'小张'),(1,'小李'),(2,'小孙'),(2,'小杨');

在MySQL中多表查询分为连接查询和子查询,连接查询又分为内连接和外连接,内连接又分为隐式内连接和显示内连接,外连接又分为左外连接和右外连接。

9.1 内连接查询

- 隐式内连接查询
select 字段列表 from1,2... where 条件;

- 显式内连接查询
select 字段列表 from1 [inner] join2 on 条件;

示例

- 隐式内连接查询
select * from class,stu where class.class_id=stu.class_id;

- 显式内连接查询
select * from class inner join stu on class.class_id=stu.class_id;

9.2 外连接查询

左外连接查询:相当于查询A表所有数据和交集部分数据

右外连接查询:相当于查询B表所有数据和交集部分数据

- 左外连接查询
select 字段列表 from1 left [outer] join2 on 条件;

- 右外连接查询
select 字段列表 from1 right [outer] join2 on 条件;

示例

select * from stu left outer join class on stu.class_id=class.class_id;

select * from stu right outer join class on stu.class_id=class.class_id;

9.3 子查询

指查询中嵌套有查询

子查询语句结果是单行单列,子查询语句作为条件值,使用>、>=、<、<=、=、!=等进行条件判断。

# class_id 大于 1班的class_id的学生
select * from stu where class_id > (select class_id from class where class_name='一班');

子查询语句结果是多行单列,子查询语句作为条件值,使用in等关键字进行条件判断

# 查询存在班级的学生
select * from stu where class_id in (select class_id from class);

子查询语句结果是多行多列,子查询语句作为虚拟表

select * from stu,(select * from class) c where stu.class_id=c.class_id;

10. 事务

使用场景:转账、下单扣库存

语法:

# 开启事务
start transaction;begin;

-- 执行各种操作

# 回滚事务
rollback;

# 提交事务
commit;

事务特征:

1、原子性,事务是不可分割最小操作单位,要么同时成功,要么同时失败

2、一致性,事务完成时,必须使所有数据都保持一致状态

3、隔离性,多个事务之间,操作可见性

4、持久性,事务一旦提交或回滚,它对数据库中数据的改变是永久的

10.1 隔离级别

数据库事务的隔离级别有4种,由低到高分别为Read uncommitted 、Read committed 、Repeatable read 、Serializable 。在事务的并发操作中可能会出现脏读,不可重复读,幻读。

读未提交(Read uncommitted):

解释:

一个事务读到了另一个事务还没有提交的数据。

例如:

A给B转账,
A转给B,10万,点转账,但未点确认
B查账户看到10万
A及时发现,点撤回,修改为1万,再点转账,再点确认

分析:

A给B最终转账是1万,但是在过程中,B能看到过程数据。这就是脏读。

读已提交(Read committed):
解释:

一个事务要等另一个事务提交后才能读取数据。

例如:

父亲的银行卡有10万
儿子拿着这个银行卡去买单,同时父亲准备转款(开启事务)。此时儿子看到银行卡里有10万
等儿子看完有10万后,钱被父亲转走,并提交
收费系统准备在这个银行卡扣款,再次检测,发现卡里没有钱了

分析:

这就是读已提交,若有事务对数据进行更新操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。
这个例子中,有读两次卡里的钱,一次是10万,一次是没有钱了,这就是不可重复读。

可重复读(Repeatable read):
解释:

同一事务下,事务在执行期间,多次读取同一数据时,能够保证读取到的数据是一致的。

例如:

父亲的银行卡有10万
儿子拿着这个银行卡去买单,此时儿子看到银行卡里有10万,这个时候父亲想转账,发现转不了
等儿子买完单,父亲才能够实行转账行为

分析:

读数据的时候,不允许该数据有写数据的事务。因为写数据会改变数据。这样子就解决了不可重复读的问题。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。

什么时候会出现幻读?

解释:

一个事务读取到了另一个事务新增的数据

例如:

儿子某一天去消费,花了8千元,然后他的父亲去查看他今天的消费记录(全表扫描,儿子事务开启),看到确实是花了8千元,就在这个时候,儿子花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。当父亲打印儿子的消费记录清单时(儿子事务提交),发现花了1.8万元,似乎出现了幻觉,这就是幻读。

串行化(Serializable):

解释:

它是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率最低,比较耗费数据库性能,一般不推荐使用。

小结:

隔离级别脏读不可重复读幻读
读未提交可能出现可能出现可能出现
读已提交不会出现可能出现可能出现
可重复读不会出现不会出现可能出现
串行化不会出现不会出现不会出现

隔离级别查询

-- MySQL8以前
SELECT @@GLOBAL.tx_isolation, @@tx_isolation;

-- MySQL8开始
SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;

修改隔离级别

-- 建议开发者在修改时,仅修改当前session隔离级别即可
-- REPEATABLE-READ,MySQL默认级别
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE-READ

11. 函数

11.1 数学函数

函数含义
abs(x)返回x的绝对值
rand()返回0到1的随机数
mod(x,y)返回x除以y以后的余数
power(x,y)返回x的y次方
round(x)返回离x最近的整数
round(x,y)保留x的y位小数四舍五入后的值
sqrt(x)返回x的平方根
truncate(x,y)返回数字 x 截断为 y 位小数的值
ceil(x)返回大于或等于 x 的最小整数
floor(x)返回小于或等于 x 的最大整数
greatest(x1,x2…)返回返回集合中最大的值
least(x1,x2…)返回返回集合中最小的值

11.2 字符串函数

函数含义
trim()返回去除指定格式的值
concat(x,y)将提供的参数 x 和 y 拼接成一个字符串
substr(x,y)获取从字符串 x 中的第 y 个位置开始的字符串,跟substring()函数作用相同
substr(x,y,z)获取从字符串 x 中的第 y 个位置开始长度为z 的字符串
length(x)返回字符串 x 的长度
replace(x,y,z)将字符串 z 替代字符串 x 中的字符串 y
upper(x)将字符串 x 的所有字母变成大写字母
lower(x)将字符串 x 的所有字母变成小写字母
left(x,y)返回字符串 x 的前 y 个字符
right(x,y)返回字符串 x 的后 y 个字符
repeat(x,y)将字符串 x 重复 y 次
space(x)返回 x 个空格
strcmp(x,y)比较 x 和 y,返回的值可以为-1,0,1
reverse(x)将字符串 x 反转

11.3 日期函数

函数含义
current_date()当前日期
current_time()当前时间
current_timestamp()当前时间戳

12. DCL

12.1 用户管理

创建用户

CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
-- 实例:
CREATE USER 'java'@'%' IDENTIFIED BY 'asd123crl';

删除用户

drop user 用户名@IP;
-- 实例:
drop user 'java'@'%';

修改密码

UPDATE `user` SET `Password` = PASSWORD('新密码') WHERE `User` = '用户名';
-- 实例:
UPDATE `user` SET `Password` = PASSWORD('asd123') WHERE `User` = 'java';

12.2 权限管理

常用权限:

  • 表数据: select, update, delete, insert
  • 表结构: create, alert, drop
  • 外键: references
  • 创建临时表: create temporary tables
  • 操作索引: index
  • 视图: create view, show view
  • 存储过程: create routine, alert routine, execute
  • 所有权限: all

查看用户权限命令

SHOW GRANTS FOR '用户名'@'主机名';
-- 实例:
SHOW GRANTS FOR 'root'@'%';

给用户授予权限

在MySQL中使用GRANT命令给用户授权,如果用户不存在,GRANT会自动创建用户,并进行授权。

GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';  -- 权限列表中如果有多个权限则用逗号,隔开
 
-- 授权所有库的所有表的所有权限
GRANT ALL ON *.* TO '用户名'@'主机名';  
-- 示例:给张三赋予db_test数据库students表的查询权限
GRANT SELECT ON db_test.students TO 'zhangsan'@'localhost';
-- 刷新权限
flush privileges

撤销权限

REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
-- 示例:撤销张三在db_test.students表的查询权限
REVOKE SELECT ON db_test.students FROM 'zhangsan'@'localhost';
-- 刷新权限
flush privileges

13. 备份与还原

备份语法:

mysqldump -h 服务器 -u 用户名 -p -B 数据库名1 数据库2 数据库n > 备份文件.sql

示例:

mysqldump -u root -p -B test > /backup/123.sql

还原语法:

mysqldump -h 服务器 -u 用户名 -p密码 --databases 数据库名 < 备份文件.sql

# 进入数据库后
source 备份文件.sql;

示例:

mysqldump -u root -p --databases test < /backup/123.sql

一般系统推荐的字符集和排序规则

# 字符集
utf8mb4

# 排序规则,不区分大小写
utf8mb4_general_cli

字符集(Character Set):utf8mb4

排序规则 | 字符序(Collate):utf8mb4_general_cli 或 utf8mb4_bin

14. 表设计流程

14.1 三级模式和两级映射

在这里插入图片描述

在这里插入图片描述

视图:一个虚拟表(逻辑上的表),其内容由查询定义(仅保存SQL查询语句)

14.2 数据库设计过程

在这里插入图片描述

14.3 需求说明和数据字典

需求说明:

能够记录学生信息(学号、姓名、性别、年龄),也能够记录课程信息(课程名、任课老师),一个学生可以选择多门课程,并需要记录学生学习课程的成绩。

数据字典:

学生信息:学号、姓名、性别、年龄

课程信息:课程名、任课老师

成绩信息:学生成绩

14.4 E-R模型

在这里插入图片描述

14.5 关系模式

学生信息表(student)

字段说明
stu_id主键
no学号
name姓名
sex性别:男、女
age年龄

课程信息表(course)

字段说明
course_id主键
course_name课程名
teacher_name任课老师

成绩信息表(score)

字段说明
score_id主键
stu_id学生主键
course_id课程主键
score分数

15. 规范化理论

非规范的关系模式或者说设计出来的数据库表,可能存在的问题:

1、数据冗余

2、更新异常

3、插入异常

4、删除异常

15.1 范式

第一范式(1NF):

数据库表的字段是不可再分的数据项。满足此规则,就是满足了第一范式。

年级名称同学人数
男同学女同学
一年级550
二年级505

第二范式(2NF):

在第一范式的基础上,如果主键是组合键时,其他字段不存在部分依赖。满足此规则,就是满足了第二范式。

学号课程号成绩学分
S01C01602
S02C01702
S03C02804
S04C02904

第三范式(3NF):

在第二范式的基础上,如果其他字段不存在传递性依赖。满足此规则,就是满足了第三范式。

学号姓名系号系名系位置
S01曹操D1计算机系1号楼
S02刘备D1计算机系1号楼
S03孙权D2信息系2号楼
S04袁绍D2信息系2号楼

开发设计表格,一般要满足三大范式,不满足怎么办?拆…

不满足第一范式:

年级名称同学人数
男同学女同学
一年级550
二年级505
| 年级名称 | 男同学 | 女同学 | | :------: | :----: | :----: | | 一年级 | 5 | 50 | | 二年级 | 50 | 5 |

不满足第二范式:

学号课程号成绩学分
S01C01602
S02C01702
S03C02804
S04C02904
学号课程号成绩
S01C0160
S02C0170
S03C0280
S04C0290
课程号学分
C012
C024

不满足第三范式:

学号姓名系号系名系位置
S01曹操D1计算机系1号楼
S02刘备D1计算机系1号楼
S03孙权D2信息系2号楼
S04袁绍D2信息系2号楼
学号姓名系号
S01曹操D1
S02刘备D1
S03孙权D2
S04袁绍D2
系号系名系位置
D1计算机系1号楼
D2信息系2号楼

拆了后存在问题,查询的时候,多表连表查询操作复杂或查询性能差。所以也存在反范式…

15.2 反范式

允许在数据库中引入冗余数据,以提高查询性能或简化查询操作…

特点:

1、冗余数据

2、数据冗余的更新

3、查询简化

运用场景:

1、高频读取、低频更新的情况

2、复杂查询和分析需求

3、数据仓库和报表生成

4、高并发和低延迟要求

5、特定优化需求

16. 并发控制

并发产生问题:

1、丢失更新

2、不可重复度读

3、读"脏"数据
在这里插入图片描述

解决方案:采用封锁协议。

S锁:读锁,也叫共享锁。若事务T对数据对象A加上S锁,则事务T可以读取A但不能修改A。其他事务只能对数据对象A加S锁,而不能加X锁,直到事务T释放对象A上的S锁。

X锁:写锁,也叫排它锁。若事务T对数据对象A加上X锁,则其他事务不能再对A加任何锁,直到事务T释放数据对象A上的锁。

一级封锁协议:

事务T1在修改数据对象A之前必须对数据对象A加上X锁,直到事务T1结束才释放X锁。可防止丢失更新。

二级封锁协议:

一级封锁协议加上事务T2在读取数据对象A之前先对其加上S锁,读完后即可释放S锁。可防止丢失更新,还可防止读"脏"数据。

三级封锁协议:

事务T1在读取数据对象A之前先对数据对象A加上S锁,直到事务结束才释放,事务T2在执行一级封锁协议。可防止丢失更新、防止读"脏"数据、防止数据重复读。

在这里插入图片描述

17. 优化

在这里插入图片描述

17.1 SQL及索引

当MySQL性能下降时,通过开启慢查询来获得哪条SQL语句造成的响应过慢,进行分析处理。

-- 是否开启慢查询
show variables like "%slow%";

-- 查询慢查询SQL状况
show status like "%slow%";

-- 慢查询时间
show variables like "long_query_time";

启用慢查询日志

1、添加或修改配置项

# 编辑MySQL配置文件(通常是my.cnf或my.ini)
[mysqld]
slow_query_log = 1 # 设置为1,启用慢查询日志
slow_query_log_file = /var/log/mysql/mysql-slow.log # 指定慢查询日志文件路径
long_query_time = 2 # 设置记录为慢查询的执行时间阈值,单位是秒

2、重启MySQL服务

慢查询分析工具:

mysqldumpslow,该工具是慢查询自带的分析慢查询工具,一般只要安装了mysql,就会有该工具

# 常用示例
# 取出使用最多的10条慢查询
mysqldumpslow -s c -t 10 /var/log/mysql/mysql-slow.log
 
# 取出查询时间最慢的3条慢查询
mysqldumpslow -s t -t 3 /var/log/mysql/mysql-slow.log

# 得到按照时间排序的前10条里面含有左连接的查询语句
mysqldumpslow -s t -t 10 -g “left join” /var/log/mysql/mysql-slow.log 
 
# 按照扫描行数最多的
mysqldumpslow -s r -t 10 -g 'left join' /var/log/mysql/mysql-slow.log

注意:使用mysqldumpslow的分析结果不会显示具体完整的sql语句,只会显示sql的组成结构

pt-query-digest,是一个perl脚本,只需下载并赋权即可执行

# 可以下载到PATH任意目录下
wget http://www.percona.com/get/pt-query-digest

chmod +x pt-query-digest
# 常用示例

# 直接分析慢查询文件
pt-query-digest slow.log > slow_report.log

# 分析最近12小时内的查询
pt-query-digest --since=12h slow.log > slow_report.log

# 分析指定时间范围内的查询
pt-query-digest slow.log --since '2024-01-01 09:30:00' --until '2024-05-01 10:00:00' > slow_report.log

explain可以用来分析SQL的执行计划

explain select * from salaries where from_date = '2024-01-01';

-- 以json 形式展示结果:
explain format=json select * from salaries where from_date = '2024-01-01';

索引

索引的目的在于提高查询效率,与我们查阅图书所用的目录是一个道理:先定位到章,然后定位到该章下的一个小节,然后找到页数。相似的例子还有:查字典,查火车车次,飞机航班等。

索引分类

1.普通索引index: 加速查找
2.唯一索引
    主键索引: primary key:加速查找+约束(不为空且唯一)
    唯一索引: unique:加速查找+约束 (唯一)
3.联合索引
    -primary key(id,name): 联合主键索引
    -unique(id,name): 联合唯一索引
    -index(id,name): 联合普通索引
4.全文索引fulltext: 用于搜索很长一篇文章的时候,效果最好。
5.空间索引spatial: 了解就好,几乎不用

索引类型

hash类型的索引:查询单条快,范围查询慢
btree类型的索引:b+树,层数越多,数据量指数级增长(innodb默认索引类型)

# 不同的存储引擎支持的索引类型也不一样
InnoDB,支持事务,支持行级别锁定,支持 B-tree、Full-text等索引,不支持 Hash 索引;
MyISAM,不支持事务,支持表级别锁定,支持 B-tree、Full-text等索引,不支持 Hash 索引;

索引使用

-- 在创建表时就创建索引
create table s1(
	id int ,#可以在这加primary key
    #id int index #不可以这样加索引,因为index只是索引,没有约束一说,
    #不能像主键,还有唯一约束一样,在定义字段的时候加索引
    name char(20),
    age int,
    email varchar(30)
    #primary key(id) #也可以在这加
    index(id) #可以这样加
);
    
-- 在创建表后再创建索引
create index name on s1(name); # 添加普通索引
create unique age on s1(age); # 添加唯一索引
alter table s1 add primary key(id); # 添加主键索引,也就是给id字段增加一个主键约束
create index name on s1(id,name); # 添加普通联合索引

-- 删除索引
drop index id on s1;
drop index name on s1; # 删除普通索引
drop index age on s1; # 删除唯一索引,就和普通索引一样,不用在index前加unique来删,直接就可以删了
alter table s1 drop primary key; # 删除主键(因为它添加的时候是按照alter来增加的,那么我们也用alter来删)

如何选择合适的列建立索引

1、在where从句,group by从句,order by从句,on从句中出现的列

2、索引字段越小越好

3、离散力度大的列放到联合索引的前面

17.2 数据库结构优化

选择合适的数据类型

1、使用可以存下业务要求的最小的数据类型

2、使用简单的数据类型。int要比varchar类型在MySQL处理上简单

3、尽可能的使用not null定义字段

4、尽量少用text类型,非用不可时最好考虑分表

表的垂直拆分

1、把不常用的字段单独存放到一个表中

2、把大字段独立存放到一个表中

3、把经常一起使用的字段放到一起

表的水平拆分

1、解决单表数据量过大的问题,单表数据达到上万条

2、水平拆分方法:

进行hash运算,如果要拆分成5个表,则使用mod(id, number)取出0-4值

假如是订单表进行水平拆分,该id应该采用用户id来mod比较合适,这样相同用户的订单会存在同一张表里

针对不同的hash把数据存到不同的表中

前台考虑性能及个人,后台考虑统计及报表业务。前台可以采用拆分后的表,后台采用汇总后的表

17.3 系统配置优化

17.3.1 操作系统配置优化

网络方面的配置

要修改/etc/sysctl.conf文件

#增加tcp支持的队列数
net.ipv4.tcp_max_syn_backlog=65535
#减少断开连接时,资源回收
net.ipv4.tcp_max_tw_buckets=8000
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1
net.ipv4.tcp_fin_timeout=10

打开文件数的限制

要修改/etc/security/limits.conf文件

*soft nofile 65535
*hard nofile 65535

除此之外最好在MySQL服务器上关闭iptables,selinux等防火墙软件

17.3.2 MySQL配置文件

查找配置文件

/etc/my.cnf
/etc/mysql/my.cnf
window(C:/windows/my.ini)

# 可以通过命令查找
mysqld --verbose --help | grep -A 1 'Default options'

注意:如果多个位置存在配置文件,则后面的同名配置项会覆盖前面的

常用参数

innodb_buffer_pool_size

配置innodb的缓冲池innodb_buffer_pool_size >= Total MB(引擎为Innodb的所有表中的数据和索引的总和)

select engine,round(sum(data_length+index_length)/1024/1024,1) as 'Total MB' from information_schema.tables where table_schema not in('information_schema','performance_schema') group by engine;

如果数据库中只有innodb表,则推荐配置量为总内存的75%

innodb_buffer_pool_instances

可以控制缓冲池的个数,默认情况下只有一个缓冲池

innodb_log_buffer_size

innode log 缓冲的大小,由于日志最长每秒钟就会刷新,所以一般不用太大

innodb_flush_log_at_trx_commit

对innodb的IO效率影响很大。值有0,1,2
默认值为1,一般建议为2,但如果数据安全性要求比较高则使用默认值1

innodb_read_io_threads和innodb_write_io_threads

决定innodb读写的IO进程数,默认为4

innodb_file_per_table

控制innodb每一个表使用独立的表空间,默认是OFF,也就是所有表都会简历在共享表空间中,建议设置成ON

innode_stats_on_metadata

决定了MySQL在什么情况下会刷新Innodb表的统计信息。建议设置成OFF

Linux配置文件一般在/etc/my.cnf或者/etc/mysql/my.cnf

windows配置文件一般在C:/windows/my.ini

如果存在多个位置存在配置文件,则后面的会覆盖前面的

第三方配置工具使用

https://tools.percona.com/wizard

17.4 服务器硬件优化

优化MySQL服务器硬件通常涉及以下几个方面:

  • 更快的处理器:使用更快的CPU,如最新一代的Intel或AMD处理器。

  • 更多的内存:增加服务器的RAM以加快磁盘访问速度。

  • 更快的存储:使用SSD(固态硬盘)替代HDD(机械硬盘)。

  • 更多的存储空间:扩展存储容量以适应数据增长。

  • 网络适配器:对于高速网络,使用10GbE或更高速率的网卡。

  • 电源:确保服务器供电足够,高效率的电源设备能提供稳定的电力。

用于检查服务器硬件规格

# 检查CPU信息
cat /proc/cpuinfo | grep "model name" | uniq
 
# 检查内存使用情况
free -h
 
# 检查存储设备类型和使用情况
lsblk
df -h
 
# 检查网络适配器
lspci | grep -i ethernet

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/568252.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

实现Spring底层机制(三)

文章目录 阶段4—实现BeanPostProcessor机制1.文件目录2.初始化方法实现1.编写初始化接口InitializingBean.java2.MonsterService.java实现初始化接口3.容器中的createBean方法增加初始化逻辑&#xff0c;判断对象类型是否是InitializingBean的子类型&#xff0c;如果是&#x…

Vue+OpenLayers7入门到实战,OpenLayers加载GeoJson数据并叠加GeoJson中的要素到地图上

返回《Vue+OpenLayers7》专栏目录:Vue+OpenLayers7入门到实战 前言 本章介绍如何使用OpenLayers7在地图上加载GeoJson数据并叠加GeoJson中的要素到OpenLayers矢量图层上。 GeoJson数据格式可以参考博主另一篇文章《GIS开发入门,GeoJSON是什么?GeoJSON格式标准介绍》,那么…

TLV61048非同步升压BOOST转换器输入电压2.6-5.5V输出电流4A输出电压最高15V

推荐原因&#xff1a; 输入电压较低&#xff0c;输出电流可达3.5A SOT23-6封装 批量价格约0.70元 TLV61048引脚 TLV61048引脚功能 7 详细说明 7.1 概述 TLV61048是一款非同步升压转换器&#xff0c;支持高达 15 V 的输出电压和输入范围从 2.61 V 到 5.5 V。该TLV61048集成了…

不用写一行代码,就能让你的公众号华丽变身成AI智能,超详细的攻略来了~

为了让你的公众号华丽变身成AI智能&#xff0c;我们用到了扣子AI&#xff0c;不用写一行代码&#xff0c;只需要三个步骤&#xff1a;创建Bot、关联公众号、发布Bot。 下面我来给你一个个讲解。 首先打开扣子官网&#xff0c;注册并登录&#xff0c;进入主页面之后就可以开始…

DSPy入门:告别指令提示,拥抱编程之旅!

原文&#xff1a;intro-to-dspy-goodbye-prompting-hello-programming 2024 年 2 月 27 日 DSPy框架如何通过用编程和编译代替提示来解决基于LLM的应用程序中的脆弱性问题。 目前&#xff0c;使用大型语言模型(LLMs)构建应用程序不仅复杂而且脆弱。典型的pipelines通常使用pr…

解决“找不到MSVCP120.dll”或“MSVCP120.dll丢失”的错误方法

在计算机使用过程中&#xff0c;遇到诸如“找不到MSVCP120.dll”或“MSVCP120.dll丢失”的错误提示并不罕见。这类问题往往会导致某些应用程序无法正常运行&#xff0c;给用户带来困扰。本文旨在详细阐述MSVCP120.dll文件的重要性、其丢失的可能原因&#xff0c;以及解决方法&a…

nginx开启basic认证

basic认证也叫做http基本认证&#xff0c;防止恶意访问 首先用在线网站生成一个叫做htpasswd的账号密码文件。 将生成结果复制到/etc/nginx/htpasswd文件中 在server的location中配置 server { listen 80; server_name a.com;location / { root html;index index.…

2001-2021年上市公司制造业智能制造词频统计数据

2001-2021年上市公司制造业智能制造词频统计数据 1、时间&#xff1a;2001-2021年 2、来源&#xff1a;上市公司年报 3、指标&#xff1a;年份、股票代码、行业名称、行业代码、所属省份、所属城市、智能制造词频、智能制造占比(%) 4、范围&#xff1a;上市公司 5、样本量…

基于TSM模块的打架斗殴识别技术

目 录 1 引言.... 4 1.1 研究背景与意义.... 4 1.2 研究现状综述.... 5 1.3 研究内容.... 6 1.3.1 图像预处理的优化.... 6 1.3.2 TSM模块的应用.... 6 1.3.3 视频分类的设计与实现.... 6 2 关键技术与方法.... 8 2.1 TSM算法与模型选择.... 8 2.1.1 TSM算法原理.... 8 2.1.2 …

深度学习-数据预处理

目录 创建一个人工数据集处理缺失的数据插入对inputs中的类别值或离散值&#xff0c;将NaN视为一个类别对inputs和outputs中的数值类型转换为张量格式 创建一个人工数据集 import os import pandas as pd os.makedirs(os.path.join(.., data), exist_okTrue) data_file os.p…

基于Vue+ElementPlus自定义带历史记录的搜索框组件

前言 基于Vue2.5ElementPlus实现的一个自定义带历史记录的搜索框组件 效果如图&#xff1a; 基本样式&#xff1a; 获取焦点后&#xff1a; 这里的历史记录默认最大存储10条&#xff0c;同时右侧的清空按钮可以清空所有历史记录。 同时搜索记录也支持点击搜索&#xff0c;按…

.NET(C#)连接达梦数据库GUID字段被自动加横线的修复方法

因信创的原因项目需要兼容达梦数据库&#xff0c;今天遇到个比较坑爹的问题&#xff0c;简单记录下解决方案。 数据库存的是这样&#xff1a; 通过DataAdapter.Fill拿出来以后变成了这样 纳尼&#xff1f;谁让你加上这些横杠的&#xff1f;&#xff08;掀桌&#xff09;导致了…

100个实用电气知识

在当今社会&#xff0c;电力作为日常生活和工作中不可或缺的能源&#xff0c;扮演着越来越重要的角色。为了更好地利用电力资源&#xff0c;了解电气知识成为了越来越多人的需求。在电气领域&#xff0c;有很多实用的知识&#xff0c;这些知识对于从事电气工作的人来说是非常重…

Linux系统安全:从面临的攻击和风险到安全加固、安全维护策略(文末有福利)

1. Linux面临的攻击与风险 1.1. Linux系统架构 Linux系统架构解读&#xff1a; 用户之间隔离内核态与用户态之间隔离用户进程一般以低权限用户运行系统服务一般以特权服务运行用户态通过系统调用进入内核态内核对系统资源进行管理和分配 1.2. Linux系统常见安全威胁 1.2.1.…

OSPF认证方式,ISIS简介,ISIS路由器类型

OSPF&#xff1a;转发&#xff0c;泛洪&#xff0c;丢弃

Docker搭建代码托管Gitlab

文章目录 一、简介二、Docker部署三、管理员使用四、用户使用五、用户客户端 一、简介 GitLab是一个基于Git的代码托管和协作平台&#xff0c;类似于GitHub。 它提供了一个完整的工具集&#xff0c;包括代码仓库管理、问题跟踪、CI/CD集成、代码审查等功能。 GitLab的开源版本…

Go语言并发赋值的安全性

struct并发赋值 type Test struct {X intY int }func main() {var g Testfor i : 0; i < 1000000; i {var wg sync.WaitGroup// 协程 1wg.Add(1)go func() {defer wg.Done()g Test{1, 2}}()// 协程 2wg.Add(1)go func() {defer wg.Done()g Test{3, 4}}()wg.Wait()// 赋值…

2024新算法角蜥优化算法(HLOA)和经典灰狼优化器(GWO)进行无人机三维路径规划设计实验

简介&#xff1a; 2024新算法角蜥优化算法&#xff08;HLOA&#xff09;和经典灰狼优化器&#xff08;GWO&#xff09;进行无人机三维路径规划设计实验。 无人机三维路径规划的重要意义在于确保飞行安全、优化飞行路线以节省时间和能源消耗&#xff0c;并使无人机能够适应复杂…

国内首个48小时大模型极限挑战赛落幕,四位“天才程序员”共同夺冠

4月21日晚&#xff0c;第四届ATEC科技精英赛&#xff08;ATEC2023&#xff09;线下赛落幕。本届赛事以大模型为技术基座&#xff0c;围绕“科技助老”命题&#xff0c;是国内首个基于真实场景的大模型全链路应用竞赛。ATEC2023线下赛采用48小时极限挑战的形式&#xff0c;来自东…

Ts支持哪些类型和类型运算(上)

目录 1、元组 2、接口&#xff08;interface&#xff09; 3、枚举&#xff08;Enum&#xff09; 4、字面量类型 5、keyof 6、in keyof 7、类型的装饰 静态类型系统 就是把 类型检查从运行时提前到了编译时&#xff0c;所以ts类型系统中的许多类型与js并无区别 例如&am…
最新文章