零基础入门学习Python第二阶04SQL详解03
MySQL 新特性
JSON类型
很多开发者在使用关系型数据库做数据持久化的时候,常常感到结构化的存储缺乏灵活性,因为必须事先设计好所有的列以及对应的数据类型。在业务发展和变化的过程中,如果需要修改表结构,这绝对是比较麻烦和难受的事情。从 MySQL 5.7 版本开始,MySQL引入了对 JSON 数据类型的支持(MySQL 8.0 解决了 JSON 的日志性能瓶颈问题),用好 JSON 类型,其实就是打破了关系型数据库和非关系型数据库之间的界限,为数据持久化操作带来了更多的便捷。
JSON 类型主要分为 JSON 对象和 JSON数组两种,如下所示。
- JSON 对象
{"name": "骆昊", "tel": "13122335566", "QQ": "957658"}
- JSON 数组
[1, 2, 3]
[{"name": "骆昊", "tel": "13122335566"}, {"name": "王大锤", "QQ": "123456"}]
哪些地方需要用到JSON类型呢?举一个简单的例子,现在很多产品的用户登录都支持多种方式,例如手机号、微信、QQ、新浪微博等,但是一般情况下我们又不会要求用户提供所有的这些信息,那么用传统的设计方式,就需要设计多个列来对应多种登录方式,可能还需要允许这些列存在空值,这显然不是很好的选择;另一方面,如果产品又增加了一种登录方式,那么就必然要修改之前的表结构,这就更让人痛苦了。但是,有了 JSON 类型,刚才的问题就迎刃而解了,我们可以做出如下所示的设计。
create table `tb_test`
(
`user_id` bigint unsigned,
`login_info` json,
primary key (`user_id`)
) engine=innodb;insert into `tb_test` values (1, '{"tel": "13122335566", "QQ": "654321", "wechat": "jackfrued"}'),(2, '{"tel": "13599876543", "weibo": "wangdachui123"}');
如果要查询用户的手机和微信号,可以用如下所示的 SQL 语句。
select `user_id`,json_unquote(json_extract(`login_info`, '$.tel')) as 手机号,json_unquote(json_extract(`login_info`, '$.wechat')) as 微信
from `tb_test`;
+---------+-------------+-----------+
| user_id | 手机号 | 微信 |
+---------+-------------+-----------+
| 1 | 13122335566 | jackfrued |
| 2 | 13599876543 | NULL |
+---------+-------------+-----------+
因为支持 JSON 类型,MySQL 也提供了配套的处理 JSON 数据的函数,就像上面用到的json_extract
和json_unquote
。当然,上面的 SQL 还有更为便捷的写法,如下所示。
select `user_id`,`login_info` ->> '$.tel' as 手机号,`login_info` ->> '$.wechat' as 微信
from `tb_test`;
再举个例子,如果我们的产品要实现用户画像功能(给用户打标签),然后基于用户画像给用户推荐平台的服务或消费品之类的东西,我们也可以使用 JSON 类型来保存用户画像数据,示意代码如下所示。
创建画像标签表。
create table `tb_tags`
(
`tag_id` int unsigned not null comment '标签ID',
`tag_name` varchar(20) not null comment '标签名',
primary key (`tag_id`)
) engine=innodb;insert into `tb_tags` (`tag_id`, `tag_name`)
values(1, '70后'),(2, '80后'),(3, '90后'),(4, '00后'),(5, '爱运动'),(6, '高学历'),(7, '小资'),(8, '有房'),(9, '有车'),(10, '爱看电影'),(11, '爱网购'),(12, '常点外卖');
为用户打标签。
create table `tb_users_tags`
(
`user_id` bigint unsigned not null comment '用户ID',
`user_tags` json not null comment '用户标签'
) engine=innodb;insert into `tb_users_tags` values (1, '[2, 6, 8, 10]'),(2, '[3, 10, 12]'),(3, '[3, 8, 9, 11]');
接下来,我们通过一组查询来了解 JSON 类型的巧妙之处。
-
查询爱看电影(有
10
这个标签)的用户ID。select * from `tb_users` where 10 member of (user_tags->'$');
-
查询爱看电影(有
10
这个标签)的80后(有2
这个标签)用户ID。select * from `tb_users` where json_contains(user_tags->'$', '[2, 10]');
-
查询爱看电影或80后或90后的用户ID。
select `user_id` from `tb_users_tags` where json_overlaps(user_tags->'$', '[2, 3, 10]');
说明:上面的查询用到了
member of
谓词和两个 JSON 函数,json_contains
可以检查 JSON 数组是否包含了指定的元素,而json_overlaps
可以检查 JSON 数组是否与指定的数组有重叠部分。
窗口函数
MySQL 从8.0开始支持窗口函数,大多数商业数据库和一些开源数据库早已提供了对窗口函数的支持,有的也将其称之为 OLAP(联机分析和处理)函数,听名字就知道跟统计和分析相关。为了帮助大家理解窗口函数,我们先说说窗口的概念。
窗口可以理解为记录的集合,窗口函数也就是在满足某种条件的记录集合上执行的特殊函数,对于每条记录都要在此窗口内执行函数。窗口函数和我们上面讲到的聚合函数比较容易混淆,二者的区别主要在于聚合函数是将多条记录聚合为一条记录,窗口函数是每条记录都会执行,执行后记录条数不会变。窗口函数不仅仅是几个函数,它是一套完整的语法,函数只是该语法的一部分,基本语法如下所示:
<窗口函数> over (partition by <用于分组的列名> order by <用户排序的列名>)
上面语法中,窗口函数的位置可以放以下两种函数:
- 专用窗口函数,包括:
lead
、lag
、first_value
、last_value
、rank
、dense_rank
和row_number
等。 - 聚合函数,包括:
sum
、avg
、max
、min
和count
等。
下面为大家举几个使用窗口函数的简单例子,我们先用如下所示的 SQL 建库建表。
-- 创建名为hrs的数据库并指定默认的字符集
create database `hrs` default charset utf8mb4;-- 切换到hrs数据库
use `hrs`;-- 创建部门表
create table `tb_dept`
(
`dno` int not null comment '编号',
`dname` varchar(10) not null comment '名称',
`dloc` varchar(20) not null comment '所在地',
primary key (`dno`)
);-- 插入4个部门
insert into `tb_dept` values (10, '会计部', '北京'),(20, '研发部', '成都'),(30, '销售部', '重庆'),(40, '运维部', '深圳');-- 创建员工表
create table `tb_emp`
(
`eno` int not null comment '员工编号',
`ename` varchar(20) not null comment '员工姓名',
`job` varchar(20) not null comment '员工职位',
`mgr` int comment '主管编号',
`sal` int not null comment '员工月薪',
`comm` int comment '每月补贴',
`dno` int not null comment '所在部门编号',
primary key (`eno`),
constraint `fk_emp_mgr` foreign key (`mgr`) references tb_emp (`eno`),
constraint `fk_emp_dno` foreign key (`dno`) references tb_dept (`dno`)
);-- 插入14个员工
insert into `tb_emp` values (7800, '张三丰', '总裁', null, 9000, 1200, 20),(2056, '乔峰', '分析师', 7800, 5000, 1500, 20),(3088, '李莫愁', '设计师', 2056, 3500, 800, 20),(3211, '张无忌', '程序员', 2056, 3200, null, 20),(3233, '丘处机', '程序员', 2056, 3400, null, 20),(3251, '张翠山', '程序员', 2056, 4000, null, 20),(5566, '宋远桥', '会计师', 7800, 4000, 1000, 10),(5234, '郭靖', '出纳', 5566, 2000, null, 10),(3344, '黄蓉', '销售主管', 7800, 3000, 800, 30),(1359, '胡一刀', '销售员', 3344, 1800, 200, 30),(4466, '苗人凤', '销售员', 3344, 2500, null, 30),(3244, '欧阳锋', '程序员', 3088, 3200, null, 20),(3577, '杨过', '会计', 5566, 2200, null, 10),(3588, '朱九真', '会计', 5566, 2500, null, 10);
例子1:查询按月薪从高到低排在第4到第6名的员工的姓名和月薪。
select * from (select `ename`, `sal`,row_number() over (order by `sal` desc) as `rank`from `tb_emp`
) `temp` where `rank` between 4 and 6;
说明:上面使用的函数
row_number()
可以为每条记录生成一个行号,在实际工作中可以根据需要将其替换为rank()
或dense_rank()
函数,三者的区别可以参考官方文档或阅读《通俗易懂的学会:SQL窗口函数》进行了解。在MySQL 8以前的版本,我们可以通过下面的方式来完成类似的操作。select `rank`, `ename`, `sal` from (select @a:=@a+1 as `rank`, `ename`, `sal` from `tb_emp`, (select @a:=0) as t1 order by `sal` desc ) t2 where `rank` between 4 and 6;
例子2:查询每个部门月薪最高的两名的员工的姓名和部门名称。
select `ename`, `sal`, `dname`
from (select `ename`, `sal`, `dno`,rank() over (partition by `dno` order by `sal` desc) as `rank`from `tb_emp`
) as `temp` natural join `tb_dept` where `rank`<=2;
说明:在MySQL 8以前的版本,我们可以通过下面的方式来完成类似的操作。
select `ename`, `sal`, `dname` from `tb_emp` as `t1`
natural join tb_dept
where (
select count(*) from tb_emp
as t2
where t1
.dno
=t2
.dno
and t2
.sal
>t1
.sal
)<2 order by dno
asc, sal
desc;
其他内容
范式理论
范式理论是设计关系型数据库中二维表的指导思想。
- 第一范式:数据表的每个列的值域都是由原子值组成的,不能够再分割。
- 第二范式:数据表里的所有数据都要和该数据表的键(主键与候选键)有完全依赖关系。
- 第三范式:所有非键属性都只和候选键有相关性,也就是说非键属性之间应该是独立无关的。
说明:实际工作中,出于效率的考虑,我们在设计表时很有可能做出反范式设计,即故意降低方式级别,增加冗余数据来获得更好的操作性能。
数据完整性
-
实体完整性 - 每个实体都是独一无二的
- 主键(
primary key
) / 唯一约束(unique
)
- 主键(
-
引用完整性(参照完整性)- 关系中不允许引用不存在的实体
- 外键(
foreign key
)
- 外键(
-
域(domain)完整性 - 数据是有效的
-
数据类型及长度
-
非空约束(
not null
) -
默认值约束(
default
) -
检查约束(
check
)说明:在 MySQL 8.x 以前,检查约束并不起作用。
-
数据一致性
-
事务:一系列对数据库进行读/写的操作,这些操作要么全都成功,要么全都失败。
-
事务的 ACID 特性
- 原子性:事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行
- 一致性:事务应确保数据库的状态从一个一致状态转变为另一个一致状态
- 隔离性:多个事务并发执行时,一个事务的执行不应影响其他事务的执行
- 持久性:已被提交的事务对数据库的修改应该永久保存在数据库中
-
MySQL 中的事务操作
-
开启事务环境
start transaction
-
提交事务
commit
-
回滚事务
rollback
-
-
查看事务隔离级别
show variables like 'transaction_isolation';
+-----------------------+-----------------+ | Variable_name | Value | +-----------------------+-----------------+ | transaction_isolation | REPEATABLE-READ | +-----------------------+-----------------+
可以看出,MySQL 默认的事务隔离级别是
REPEATABLE-READ
。 -
修改(当前会话)事务隔离级别
set session transaction isolation level read committed;
重新查看事务隔离级别,结果如下所示。
+-----------------------+----------------+ | Variable_name | Value | +-----------------------+----------------+ | transaction_isolation | READ-COMMITTED | +-----------------------+----------------+
关系型数据库的事务是一个很大的话题,因为当存在多个并发事务访问数据时,就有可能出现三类读数据的问题(脏读、不可重复读、幻读)和两类更新数据的问题(第一类丢失更新、第二类丢失更新)。想了解这五类问题的,可以阅读我发布在 CSDN 网站上的《Java面试题全集(上)》一文的第80题。为了避免这些问题,关系型数据库底层是有对应的锁机制的,按锁定对象不同可以分为表级锁和行级锁,按并发事务锁定关系可以分为共享锁和独占锁。然而直接使用锁是非常麻烦的,为此数据库为用户提供了自动锁机制,只要用户指定适当的事务隔离级别,数据库就会通过分析 SQL 语句,然后为事务访问的资源加上合适的锁。此外,数据库还会维护这些锁通过各种手段提高系统的性能,这些对用户来说都是透明的。想了解 MySQL 事务和锁的细节知识,推荐大家阅读进阶读物《高性能MySQL》,这也是数据库方面的经典书籍。
ANSI/ISO SQL 92标准定义了4个等级的事务隔离级别,如下表所示。需要说明的是,事务隔离级别和数据访问的并发性是对立的,事务隔离级别越高并发性就越差。所以要根据具体的应用来确定到底使用哪种事务隔离级别,这个地方没有万能的原则。
总结
关于 SQL 和 MySQL 的知识肯定远远不止上面列出的这些,比如 SQL 本身的优化、MySQL 性能调优、MySQL 运维相关工具、MySQL 数据的备份和恢复、监控 MySQL 服务、部署高可用架构等,这一系列的问题在这里都没有办法逐一展开来讨论,那就留到有需要的时候再进行讲解吧,各位读者也可以自行探索。
相关文章:

零基础入门学习Python第二阶04SQL详解03
MySQL 新特性 JSON类型 很多开发者在使用关系型数据库做数据持久化的时候,常常感到结构化的存储缺乏灵活性,因为必须事先设计好所有的列以及对应的数据类型。在业务发展和变化的过程中,如果需要修改表结构,这绝对是比较麻烦和难…...

【第二节】C/C++数据结构之线性表
目录 一、线性表基本说明 1.1 基本概念 1.2 抽象数据类型 1.3 存储结构 1.4 插入与删除的区别 1.5 顺序存储和链式存储的优缺点 二、链表 2.1 基本概念 2.2 抽象数据类型 2.3 单链表的定义 2.4 单链表的基本操作 2.5 单链表模板形式的类定义与实现 三、单向循环链…...

千帆 AppBuilder 工作流编排功能直播总结
千帆 AppBuilder 工作流编排功能直播总结 上个月,千帆AppBuilder推出了一项引人瞩目的新功能——工作流编排。在官方直播中,百度产品经理不仅深入介绍了这项功能,而且还通过创建多个组件,生动展示了AppBuilder组件工作流的强大…...

Android百度人脸识别3.0配置
JDK 必须是16的版本 如果报错的错误是"opens java.io" org.gradle.jvmargs -Xmx2048M -Dkotlin.daemon.jvm.options\"-Xmx2048M" --add-exportsjava.base/sun.nio.chALL-UNNAMED --add-opensjava.base/java.langALL-UNNAMED --add-opensjava.base/java.…...

dolphinscheduler docker部署海豚mysql版本,docker重新封装正在运行服务为镜像
1.官方文档: https://dolphinscheduler.apache.org/zh-cn/docs/3.2.1/guide/installation/standalone#%E9%85%8D%E7%BD%AE%E6%95%B0%E6%8D%AE%E5%BA%93 2.github: dolphinscheduler/docs/docs/zh/guide/howto/datasource-setting.md at 3.2.1-release apache/do…...

QAnything-1.4.01.4.1版本更新!使用指北!
久等了各位!时隔一个多月,我们在4月26日和5月20日接连发布了v1.4.0和v1.4.1两个版本,带来了问答性能,解析效果等多方面的改进,并新增了大量的新功能和新特性 详见:releases 以及 使用说明 最新特性表 开发…...

【ARM】Fusa Compiler 6.16 LTS的安全认证报告获取
【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 了解ARM的Arm Compiler for Embedded FuSa 6.16 LTS的安全认证证书和报告的获取 2、 问题场景 对于使用了ARM DS Gold/Platinum、MDK pro或者Arm Compiler for Embedded FuSa 6.16 LTS产品的客户。在对于最终的产品…...

数据持久化第七课-URL重写与Ajax
数据持久化第七课-URL重写与Ajax 一.预习笔记 1.URL重写(对网页地址进行保护) 首先编写module,实现对网络地址的处理 其次就是module的配置 最后验证url重写技术 2.Ajax数据交互 编写后端响应数据 处理跨域的配置问题 运行项目得到后端响应数据的地址 编写前端ajax进行数据请…...

静态网页实现-人脸识别-案例(web)
🤳人脸识别(web) 基于开源大模型,将人脸识别功能整合到网页中,提供用户友好的界面和强大的功能。 核心功能 人脸轮廓识别: 通过深度学习算法,精确识别人脸的轮廓,包括眼睛、鼻子、嘴巴等关键部…...

ARM32开发——串口输入
🎬 秋野酱:《个人主页》 🔥 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 需求串口数据接收中断函数IDLE中断串口接收流程(了解)完整示例 需求 串口接收PC机发送的数据。 串口数据接…...

个人笔记--python用tanh画圆形,正方形,长方形(epsilon界面宽度)
用tanh函数画图 圆形 import numpy as np import matplotlib.pyplot as plt# 创建一个二维网格 xx np.linspace(-1, 1, 1000) yy np.linspace(-1, 1, 1000) x_i, y_i np.meshgrid(xx, yy)# 圆的半径和中心 r 0.4 center_x, center_y 0, 0 # 假设圆心在(0, 0)# 计算每个网…...

学习Java,stringbuilder用法
有sb.append添加元素,sb.reverse反转内容,sb.tostring转换成字符串,sb.length计算长度。...
16-云原生监控体系-rabbitmq_exporter监控 RabbitMQ-[部署Dashborad告警规则实战]
文章目录 1. 二进制方式部署1.1. 二进制包下载和部署1.2. 配置1.2.1. 可用的环境变量1.2.2. 使用变量2. docker-compose 方式部署3. 配置到 Prometheus3. Metrics3.1. 全局3.2. 基础信息3.3. Queues3.3.1 Queues - Gauge3.3.2. Queues - Counter...
四大运营商频段-2024
四大运营商频段-2023 中国移动900MHz(Band8),889-904/934-949MHz:1.8GHz(Band3),1710-1735/1805-1830MHz:1.9GHz(Band39),1885-1915MHz:2GHz(Band34),2010-2025MHz:2.3GHz(Band40),2320-2370MHz:2.6GHz(Band41,n41),25…...

260只出现一次的数字
一:题目描述 二:思路讲解 三:代码 class Solution { public:vector<int> singleNumber(vector<int>& nums) {int sum 0;for(const int& e : nums){sum ^ e;}int l (sum INT_MIN ? sum : sum&(-sum));int sum1 0…...

【高阶数据结构(八)】跳表详解
💓博主CSDN主页:杭电码农-NEO💓 ⏩专栏分类:高阶数据结构专栏⏪ 🚚代码仓库:NEO的学习日记🚚 🌹关注我🫵带你学习更多数据结构 🔝🔝 高阶数据结构 1. 前言2. 跳表的概…...
用旧安卓手机当 linux 开发机
1. 下载 Termux (快速链接,如果失效或者要下载最新版请去github release 下载 ) 注意手机硬件,我这个是 64 的所以下 64 的 https://github.com/termux/termux-app/releases/download/v0.118.0/termux-app_v0.118.0github-debug_arm64-v8a.apk 2. 弄到…...

discuz如何添加主导航
大家好,今天教大家怎么样给discuz添加主导航。方法其实很简单,大家跟着我操作既可。一个网站的导航栏是非常重要的,一般用户进入网站的第一印象就是看网站的导航栏。如果大家想看效果的话可以搜索下网创有方,或者直接点击查看效果…...
[每日一练]患某种疾病的患者,正则表达式的匹配
该题目来源于力扣: 1527. 患某种疾病的患者 - 力扣(LeetCode) 题目要求: 患者信息表: Patients ----------------------- | Column Name | Type | ----------------------- | patient_id | int | | pati…...
PHP身份证识别接口、线上平台如何实现身份证实名认证功能?
线上平台实现身份证实名认证的功能,需要结合身份证识别接口来完成。首先,用户通过上传身份证图片或者拍照的方式实现证件信息的提取,身份证实名认证接口通过对提取到的证件信息进行核验,以此来实现线上用户身份的实名认证…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...