带你了解现行数据库的高级特性和新方法

阅读指南:
本文探讨了数据库的高级特性和新方法,详细介绍了这些高级特性及其操作方式,并涵盖了一些最新的操作方法。如果读者感兴趣,我们将会在后续的数据库教程合集里更新更多高级操作内容,欢迎大家与我们一起学习和讨论。这篇文章是本系列的最后一篇,感谢大家的阅读和支持。
合集链接:
数据库详细基础教程

数据库的高级操作

数据库事务

数据库事务概述:

  • 数据库事务是一套操作数据命令的有序集合,一个不可分割的工作单位。

  • 事务中单个命令不会立刻改变数据库数据,当内部全部的命令都生效且成功时,才算一次成功,如果有任一任务失败,可以进行状态回滚

  • 事务哟事务开始与事务结束之间执行的全部数据库操作组成

事务的作用:

  • 为数据库提供了一个从失败中恢复到正常状态的方法
  • 当对个应用程序在并发访问数据库时,可以有效避免彼此的操作互相干扰

♦️事务的ACID特性:

  1. 原子性(Automicity)

​ 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

  1. 一致性(Consistency)

​ 一致性是指事务内部的操作的状态前后一致,即成功则都成功,失败则都失败。

  1. 隔离性(Isolation)

​ 隔离性是指一个事物的执行不能被其他事物干扰,即一个事物内部的操作即使用的数据对并发的其他事务是隔离的,并发实现的各个事务之间都不能相互干扰。

  1. 持久性(Durability)

​ 持久性是指一个事物一旦被提交,他对数据库中数据的改变就是永久性的,后面的操作对其不成影响。

事务的开启,提交,回滚:

前提:

​ MySQL默认情况下是自动提交事务的。

​ 默认每一条语句都是一个独立的事务,一旦成功就提交了。语句失败报错就回滚。

​ 那要将多条语句作为一个事物,有如下方法

方法一:手动提交模式

# 开启手动提交模式,这个模式的生命周期只在一次服务时间内,也就是说,如果关闭了sql服务,则再次打开时需要再一次开启,最好在终端进行操作
SET AUTOCOMMIT = FALSE;
或 
SET AUTOCOMMIT = 0;

# 恢复自动提交
SET AUTOCOMMIT = TRUE; 
或 
SET AUTOCOMMIT = 1;

# 查看是否自动提交
SHOW VARIABLES LIKE 'AUTOCOMMIT';

# 成功 —> 提交,失败 -> 回滚
    COMMIT;     ROLLBACK;

方法二: 自动提交模式下开启独立事务

START TRANSACTION;	# 开启独立事务

..........	# 多个sql命令

COMMIT;ROLLBACK;

注:
事务只支持在update,insert,delete这类对数据产生变化的方法中,不支持删表,删库那种操作。

事务的隔离性:

​ 一个书屋内部的操作即使用的数据对并发的其他事物是隔离的,并发执行的各事务之间不能相互干扰

隔离级别概述脏读不可重复读幻读
read-uncommitted读未提交事务数据
read-committed读已提交事务数据(orcle默认)×
repeatable-read可重复度(MySQL默认)××√(小概率)
aseializable串行化和序列化×××

脏读:一个事务读取了另一个事务未提交的数据

不可重复读取:一个事务读取了另一个事务所提交的修改数据,不符合数据的一致性

幻读:一个事务读取了另一个事务新增,删除的记录情况,与实际情况不同。

# 改变隔离级别
SET TRANSACTION_ISOLATION = '隔离级别';

# 查看隔离级别
SELEC T@@TRANSACTION_ISOLATION;

注:

隔离等级越高,越安全,但是性能越低。

用户权限控制

​ 授予的权限可分为三个级别:数据库级别,表级别或特定操作上。

创建用户语法:

CREATE USER 'username' @ '服务器ip地址(%代表所有ip)' IDENTIFIED BY 'password';
# username 表示要创建的用户的用户名
# password 表示创建的用户的用户名

赋予权限语法:

# 1. 赋予全部权限
GRANT ALL PRIVIEGES ON 库名(*代表全部).表名(*代表全部) TO 'username' @ '服务器ip地址(%代表所有ip)';
# 2.指定库和权限
GRANT SELECT, INSERT ON 库名.表名 TO 'username' @ '服务器ip地址(%代表所有ip)';

回收权限语法:

# 撤销全部权限
REMOVE ALL PRIVILEGES ON database_name.* FROM 'username' @ 'IP';
# 撤销部分权限
REMOVE SELECT, INSERT,UPDATE ON database_name.table_name FROM 'username' @ 'IP';

查看权限语法:

# 查看权限
SHOW GRANTS FOR 'username' @ 'IP';

# 查看有用户列表
SELECT User, Host FROM mysql.user;

删除用户语法:

# 删除用户
DROP USER '用户名';

数据的备份与还原

全量备份

# 备份单库和单表的数据
mysqldump -u username -p database_name 表名>backup.sql

# 备份单库和多表
mysqldump -u username -p database_name 表名1 表名2...>backup.sql

# 备份单库的所有表
mysqldump -u username -p database_name > backup.sql

#-p如果写密码,必须紧贴着
# 以上命令必须在未连mysql的状态下执行(CMD执行)

全量恢复

# 还原数据
mysql -u username -p database_name < backup.sql

# 需要提前准备数据库,导入已存在的数据库,同时,数据库的MySQ版本要兼容

Binlog运行日志

​ Binlog日志是一个MySQL的二进制的日志记录,里面记录了数据库所有的增删改查的操作,同时也包括了操作的执行时间,所以,我们可以通过该日志查询误删除数据的恢复,增量复制,主从同步等。

Binlog配置文件的地址

​ 默认在:MySQL服务/my.ini

​ 其中有一部分是

[mysqld]
……
datadir = MySQL服务/Data    # 默认的存储详细Binlog的二进制文件地址
……
log-bin = Binlog的文件名	# 此处Binlog的文件名默认是以电脑名称命名,可以修改

对日志的操作(以下操作在 SQLyog 中使用):

示例:

# 清空原有日志文件
RESET MASTER;

# 准备数据,插入数据 --> 00000001日志文件
CREATE DATABASE text_binlog;
USE text_binlog;
CREATE TABLE table_binlog(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(20) NOT NULL
);
INSERT INTO table_binlog (NAME) VALUES ('二狗子'),('驴蛋蛋');

# 重启一个新的日志文件 --> 00000002日志文件
FLUSH LOGS;		# 创建一个新日志

# 将删除数据和插入数据植入到第二个日志文件中-->00000002日志文件
DELETE FROM table_binlog WHERE id = 2;	  # 删除驴蛋蛋
INSERT INTO table_binlog(NAME) VALUES('狗剩子');
SELEC *FROM table_binlog;

# 查看日志文件目录
SHOW BINARY LOGS;

# 查兰某个日志的命令清单
# 语法:
SHOW BINARY EVENTS;		查看第一个日志的清单
SHOW BINARY EVENTS IN '清单名' [FROM pos(具体信息位置) LIMIT OFSET, NUMBER]0; 
# 实例:
SHOW BINARY EVENTS IN 'MY_LOGIN.00000002' FROM 391 LIMIT 1, 3;

CMD下的日志操作:

注:在binlog的文件目录下进行cmd

# 跳过步骤找回数据
mysqlbinlog my-logbin.000001> d:/my_binlog.000001.sql # 将其他的日志完整导出
mysqlbinlog --stop-POSITION=删除命令的开始的pos my-logbin.000002> d:/my_binlog.391.sql # 02日志删除之前
mysqlbinlog --start-POSITION=删除命令的下一个命令开始pos my-logbin.000002> d:/my_binlog.441.sql # 02日志删除之后

数据库的新特性

窗口函数的使用

窗口函数:

  • 序号函数: row_number()

  • 序号函数: rank()

  • 序号函数: dense_rank()

  • 分步函数: PERCENT_RANK()

    (rank - 1) 1 / (rows - 1)

  • 前后函数: LAG(expr,n)

    LAG(expr,n)函数返回当前行的前n行的expr的值。

  • 首尾函数: FIRST_VALUE(expr)

    FIRST_VALUE(expr)函数返回第一个expr的值。

示例:

数据的准备

CREATE TABLE goods(
 id INT PRIMARY KEY AUTO_INCREMENT,
 category_id INT,
 category VARCHAR(15),
 NAME VARCHAR(30),
 price DECIMAL(10,2),
 stock INT,
 upper_time DATETIME
);


INSERT INTO goods(category_id,category,NAME,price,stock,upper_time)
VALUES
(1, '女装/女士精品', 'T恤', 39.90, 1000, '2020-11-10 00:00:00'),
(1, '女装/女士精品', '连衣裙', 79.90, 2500, '2020-11-10 00:00:00'),
(1, '女装/女士精品', '卫衣', 89.90, 1500, '2020-11-10 00:00:00'),
(1, '女装/女士精品', '牛仔裤', 89.90, 3500, '2020-11-10 00:00:00'),
(1, '女装/女士精品', '百褶裙', 29.90, 500, '2020-11-10 00:00:00'),
(1, '女装/女士精品', '呢绒外套', 399.90, 1200, '2020-11-10 00:00:00'),
(2, '户外运动', '自行车', 399.90, 1000, '2020-11-10 00:00:00'),
(2, '户外运动', '山地自行车', 1399.90, 2500, '2020-11-10 00:00:00'),
(2, '户外运动', '登山杖', 59.90, 1500, '2020-11-10 00:00:00'),
(2, '户外运动', '骑行装备', 399.90, 3500, '2020-11-10 00:00:00'),
(2, '户外运动', '运动外套', 799.90, 500, '2020-11-10 00:00:00'),
(2, '户外运动', '滑板', 499.90, 1200, '2020-11-10 00:00:00');

使用聚合函数的方式

# 聚合函数也是窗口函数 [理解]
# 查询所有的商品编号,价格,和类别名以及整体平均价格

SELECT id , NAME ,price, category , AVG(price) OVER () FROM goods;

SELECT id , NAME , price , category , AVG(price) OVER() FROM goods ;

# 查询所有的商品编号,价格,和类别名以及类别平均价格
SELECT id , NAME ,price, category , AVG(price) OVER (PARTITION BY category) FROM goods;

SELECT id , NAME , price , category , AVG(price) OVER(PARTITION BY category_id) FROM goods ;

使用窗口函数:

# 查询 goods 数据表中每个商品分类下价格降序排列的各个商品信息。
SELECT ROW_NUMBER() OVER(PARTITION BY category ORDER BY price DESC) AS num,id , category , NAME ,price FROM goods;

SELECT ROW_NUMBER() OVER(PARTITION BY category_id ORDER BY price DESC) AS row_num, id,
 category_id, category, NAME, price, stock FROM goods;
# 窗口函数 over (partition by 分组 order by 排序 )

# 查询 goods 数据表中每个商品分类下价格最高的3种商品信息。
SELECT * FROM ( SELECT ROW_NUMBER() OVER(PARTITION BY category_id ORDER BY price DESC) AS row_num, 
id, category_id, category, NAME, price, stock FROM goods) t
 WHERE row_num <= 3;
  

# 使用RANK()函数获取 goods 数据表中各类别的价格从高到低排序的各商品信息。
SELECT RANK() OVER(PARTITION BY category_id ORDER BY price DESC) AS row_num,
    id, category_id, category, NAME, price, stock
    FROM goods;

# 使用RANK()函数获取 goods 数据表中类别为“女装/女士精品”的价格最高的4款商品信息
 SELECT * FROM(
    SELECT RANK() OVER(PARTITION BY category_id ORDER BY price DESC) AS row_num,
    id, category_id, category, NAME, price, stock
    FROM goods) t
    WHERE category_id = 1 AND row_num <= 4;


# 使用DENSE_RANK()函数获取 goods 数据表中各类别的价格从高到低排序的各商品信息。
SELECT DENSE_RANK() OVER(PARTITION BY category_id ORDER BY price DESC) AS row_num, id, category_id, category, NAME, price, stock  FROM goods;

# 使用DENSE_RANK()函数获取 goods 数据表中类别为“女装/女士精品”的价格最高的4款商品信息。
SELECT * FROM( SELECT DENSE_RANK() OVER(PARTITION BY category_id ORDER BY price DESC) AS row_num,  id, category_id, category, NAME, price, stock FROM goods) t WHERE category_id = 1 AND row_num <= 3;



# 计算 goods 数据表中名称为“女装/女士精品”的类别下的商品的PERCENT_RANK值。
# 写法一:
SELECT RANK() OVER (PARTITION BY category_id ORDER BY price DESC) AS r,PERCENT_RANK() 
OVER (PARTITION BY category_id ORDER BY price DESC) AS pr,id, category_id, category, 
NAME, price, stock FROM goods WHERE category_id = 1;

# 写法二:
SELECT RANK() OVER w AS r,
     PERCENT_RANK() OVER w AS pr,
     id, category_id, category, NAME, price, stock
     FROM goods
     WHERE category_id = 1 WINDOW w AS (PARTITION BY category_id ORDER BY price DESC);
     


# 查询goods数据表中前一个商品价格与当前商品价格的差值。
SELECT id, category, NAME, price, pre_price, price - pre_price AS diff_price
   FROM (SELECT  id, category, NAME, price,LAG(price,1) OVER w AS pre_price FROM goods
   WINDOW w AS (PARTITION BY category_id ORDER BY price)) t;


# 按照价格排序,查询第1个商品的价格信息。
SELECT id, category, NAME, price, stock,FIRST_VALUE(price) OVER w AS first_price
    FROM goods WINDOW w AS (PARTITION BY category_id ORDER BY price);
  • 26
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值