八股之数据库

news2024/9/21 4:22:11

一、Mysql 基础知识

1.为什么不推荐使用外键与级联?

  • 增加了复杂性: a. 每次做 DELETE 或者 UPDATE 都必须考虑外键约束,会导致开发的时候很痛苦, 测试数据极为不方便; b. 外键的主从关系是定的,假如那天需求有变化,数据库中的这个字段根本不需要和其他表有关联的话就会增加很多麻烦。
  • 增加了额外工作:数据库需要增加维护外键的工作,比如当我们做一些涉及外键字段的增,删,更新操作之后,需要触发相关操作去检查,保证数据的的一致性和正确性,这样会不得不消耗数据库资源。如果在应用层面去维护的话,可以减小数据库压力;
  • 对分库分表不友好:因为分库分表下外键是无法生效的。

外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度

2.默认字符集

在 MySQL5.7 中,默认字符集是 latin1 ;在 MySQL8.0 中,默认字符集是 utf8mb4

3.字段类型

4.VARCHAR(100)和 VARCHAR(10)的区别是什么?

二者存储的字符范围不同,但存储相同的字符串,所占用磁盘的存储空间相同

不过,VARCHAR(100) 会消耗更多的内存。这是因为 VARCHAR 类型在内存中操作时,通常会分配固定大小的内存块来保存值,即使用字符类型中定义的长度。例如在进行排序的时候,VARCHAR(100)是按照 100 这个长度来进行的,也就会消耗更多内存。

5.DECIMAL 和 FLOAT/DOUBLE 的区别是什么?

DECIMAL 是定点数,FLOAT/DOUBLE 是浮数

DECIMAL 用于存储具有精度要求的小数,例如与货币相关的数据,可以避免浮点数带来的精度损失。在 Java 中,MySQL 的 DECIMAL 类型对应的是 Java 类 java.math.BigDecimal

 二、事务

1.事务的特性

  • 原子性Atomicity):事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
  • 一致性Consistency):执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
  • 隔离性Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
  • 持久性Durability):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

2.并发事务带来的问题

脏读(Dirty read):B事务读取了A事务还未提交的数据后A事务回滚,数据并没有提交到数据库

丢失修改(Lost to modify):A、B事务读取同一个数据,A事务修改该数据后B事务也修改了该数据,导致A事务的修改丢失

不可重复读(Unrepeatable read):A事务内多次读同一数据,在A事务还未结束时,B事务也访问该数据并做出修改,导致A事务两次读到的数据不一样

幻读(Phantom read):A事务读取了几行数据后,并发事务B插入了一些数据,在随后的查询中,A事务发现多了一些原本不存在的记录

3.SQL事务隔离级别

  • READ-UNCOMMITTED(读未提交) :允许读取尚未提交的数据变更
  • READ-COMMITTED(读已提交) :允许读取并发事务已经提交的数据
  • REPEATABLE-READ(可重复读) :对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改(MySQL默认隔离级别)
  • SERIALIZABLE(可串行化) :所有的事务依次逐个执行,事务之间不产生干扰
隔离级别脏读不可重复读幻读
READ-UNCOMMITTED
READ-COMMITTED×
REPEATABLE-READ××
SERIALIZABLE×××

 4.SQL优化

避免使用select *

用union all代替union

小表驱动大表

批量操作

多用limit

in中值太多

增量查询

高效的分页

用连接查询代替子查询

join的表不宜过多

二、Redis

1.Redis 为什么这么快

  • Redis 基于内存,内存的访问速度比磁盘快很多
  • Redis 基于 Reactor 模式设计开发了一套高效的事件处理模型,主要是单线程事件循环和 IO 多路复用
  • Redis 内置了多种优化过后的数据类型/结构实现,性能非常高
  • Redis 通信协议实现简单且解析高效

2.Redis常用数据类型

  • 5 种基础数据类型:String(字符串)、List(列表)、Hash(散列)、Set(集合)、Zset(有序集合)
  • 3 种特殊数据类型:Bitmap (位图)、HyperLogLog(基数统计)、Geospatial (地理位置)

Redis 5 种基本数据类型对应的底层数据结构实现如下表所示:

StringListHashSetZset
SDSLinkedList/ZipList/QuickListDict、ZipListDict、IntsetZipList、SkipList

(1)String

String 是一种二进制安全的数据类型,可以用来存储任何类型的数据比如字符串、整数、浮点数、图片、序列化后的对象,一个String的value最多可以是512M

String的数据结构为简单动态字符串(Simple Dynamic String),是可修改的字符串,内部结构实现上类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配

(2)List

List 的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销

(3)Hash

Hash 是一个 String 类型的 field-value(键值对)的映射表,特别适用于存储对象,内部实现为数组 + 链表

(4)Set

Set是一种无序集合,且集合中的元素唯一,可以基于 Set 轻易实现交集、并集、差集的操作

常见应用场景:

  • 存放的数据不能重复:网站 UV 统计、文章点赞、动态点赞
  • 获取多个数据源交、并、差集:共同好友(交集)、共同粉丝(交集)、共同关注(交集)、好友推荐(差集)、音乐推荐(差集)、订阅号推荐(差集+交集)
  • 随机获取元素:抽奖系统、随机点名

(5)Zset

Sorted Set 类似于 Set,但增加了一个权重参数 score 用来有序排列,还可以通过 score 的范围来获取元素的列表,有点像是 Java 中 HashMapTreeSet 的结合体

ZSet 有两种不同的实现,分别是 ziplist 和 skiplist,具体使用哪种结构进行存储的规则如下:

  • 当有序集合对象同时满足以下两个条件时,使用 ziplist:
    1. ZSet 保存的键值对数量少于 128 个;
    2. 每个元素的长度小于 64 字节。
  • 如果不满足上述两个条件,那么使用 skiplist 

(6)Bitmap

Bitmap 存储的是连续的二进制数字(0 和 1),通过 Bitmap, 只需要一个 bit 位来表示某个元素对应的值或者状态

(7)HyperLogLog

像UV(UniqueVisitor,独立访客)、独立IP数、搜索记录数等需要去重和计数的问题称为基数问题。

解决基数问题有很多种方案:

(1)数据存储在MySQL表中,使用distinct count计算不重复个数

(2)使用Redis提供的hash、set、bitmaps等数据结构来处理

以上的方案结果精确,但随着数据不断增加,导致占用空间越来越大,对于非常大的数据集是不切实际的。

HyperLogLog 是一种有名的基数计数概率算法 ,基于 LogLog Counting(LLC)优化改进得来,并不是 Redis 特有的,Redis 只是实现了这个算法并提供了一些开箱即用的 API。

Redis 提供的 HyperLogLog 占用空间非常非常小,只需要 12k 的空间就能存储接近2^64个不同元素。这是真的厉害,这就是数学的魅力么!并且,Redis 对 HyperLogLog 的存储结构做了优化,采用两种方式计数:

  • 稀疏矩阵:计数较少的时候,占用空间很小。
  • 稠密矩阵:计数达到某个阈值的时候,占用 12k 的空间

(8)Geospatial

3.String 还是 Hash 存储对象数据更好呢?

  • String 存储的是序列化后的对象数据,存放的是整个对象。Hash 是对对象的每个字段单独存储,可以对部分字段进行增删改查,节省网络流量
  • String 存储相对来说更加节省内存,缓存相同数量的对象数据,String 消耗的内存约是 Hash 的一半。并且,存储具有多层嵌套的对象时也方便很多。如果系统对性能和资源消耗非常敏感的话,String 就非常适合。

在绝大部分情况,建议使用 String 来存储对象数据

4.Redis 的有序集合底层为什么要用跳表,而不用平衡树、红黑树或者 B+树?

  • 平衡树 vs 跳表:平衡树的插入、删除和查询的时间复杂度和跳表一样都是 O(log n)。对于范围查询来说,平衡树也可以通过中序遍历的方式达到和跳表一样的效果。但是它的每一次插入或者删除操作都需要保证整颗树左右节点的绝对平衡,只要不平衡就要通过旋转操作来保持平衡,这个过程是比较耗时的。跳表诞生的初衷就是为了克服平衡树的一些缺点。跳表使用概率平衡而不是严格强制的平衡,因此,跳表中的插入和删除算法比平衡树的等效算法简单得多,速度也快得多。
  • 红黑树 vs 跳表:相比较于红黑树来说,跳表的实现也更简单一些,不需要通过旋转和染色(红黑变换)来保证黑平衡。并且,按照区间来查找数据这个操作,红黑树的效率没有跳表高。
  • B+树 vs 跳表:B+树更适合作为数据库和文件系统中常用的索引结构之一,它的核心思想是通过可能少的 IO 定位到尽可能多的索引来获得查询数据。对于 Redis 这种内存数据库来说,它对这些并不感冒,因为 Redis 作为内存数据库它不可能存储大量的数据,所以对于索引不需要通过 B+树这种方式进行维护,只需按照概率进行随机维护即可,节约内存。而且使用跳表实现 zset 时相较前者来说更简单一些,在进行插入时只需通过索引将数据插入到链表中合适的位置再随机维护一定高度的索引即可,也不需要像 B+树那样插入时发现失衡时还需要对节点分裂与合并。

5.Redis 性能优化

(1)使用批量操作减少网络传输

一个 Redis 命令的执行可以简化为:发送命令 -> 命令排队 -> 命令执行 -> 返回结果

其中,第 1 步和第 4 步耗费时间之和称为 Round Trip Time (RTT,往返时间) ,也就是数据在网络上传输的时间。

使用批量操作可以减少网络传输次数,进而有效减小网络开销,大幅减少 RTT。

此外,发送一次命令的 socket I/O 成本也比较高(涉及上下文切换,存在read()write()系统调用),批量操作还可以减少 socket I/O 成本

(2)大量 key 集中过期问题

对于过期 key,Redis 采用的是 定期删除+惰性/懒汉式删除 策略

定期删除执行过程中,如果突然遇到大量过期 key,客户端请求必须等待定期清理过期 key 任务线程执行完成,导致客户端请求没办法被及时处理

解决方法:

  1. 给 key 设置随机过期时间
  2. 开启 lazy-free(惰性删除/延迟释放) 。lazy-free 特性是 Redis 4.0 开始引入的,指的是让 Redis 采用异步方式延迟释放 key 使用的内存,将该操作交给单独的子线程处理,避免阻塞主线程

建议不管是否开启 lazy-free,都尽量给 key 设置随机过期时间

(3)bigkey

如果一个 key 对应的 value 所占用的内存比较大,那这个 key 就可以看作是 bigkey。大概的参考标准:

  • String 类型的 value 超过 1MB
  • 复合类型(List、Hash、Set、Sorted Set 等)的 value 包含的元素超过 5000 个(不过,对于复合类型的 value 来说,不一定包含的元素越多,占用的内存就越多)。

bigkey 通常是由于下面这些原因产生的:

  • 程序设计不当,比如直接使用 String 类型存储较大的文件对应的二进制数据。
  • 对于业务的数据规模考虑不周到,比如使用集合类型的时候没有考虑到数据量的快速增长。
  • 未及时清理垃圾数据,比如哈希中冗余了大量的无用键值对。

bigkey 除了会消耗更多的内存空间和带宽,还会对性能造成比较大的影响。

大 key 还会造成阻塞问题。具体来说,主要体现在下面三个方面:

  1. 客户端超时阻塞:由于 Redis 执行命令是单线程处理,然后在操作大 key 时会比较耗时,那么就会阻塞 Redis,从客户端这一视角看,就是很久很久都没有响应。
  2. 网络阻塞:每次获取大 key 产生的网络流量较大,如果一个 key 的大小是 1 MB,每秒访问量为 1000,那么每秒会产生 1000MB 的流量,这对于普通千兆网卡的服务器来说是灾难性的。
  3. 工作线程阻塞:如果使用 del 删除大 key 时,会阻塞工作线程,这样就没办法处理后续的命令。

大 key 造成的阻塞问题还会进一步影响到主从同步和集群扩容。

(4)hotkey

在 Redis 实例的每秒处理请求达到 5000 次,而其中某个 key 的每秒访问量就高达 2000 次,那这个 key 就可以看作是 hotkey

hotkey 出现的原因主要是某个热点数据访问量暴增,如重大的热搜事件、参与秒杀的商品。

处理 hotkey 会占用大量的 CPU 和带宽,可能会影响 Redis 实例对其他请求的正常处理。此外,如果突然访问 hotkey 的请求超出了 Redis 的处理能力,Redis 就会直接宕机。这种情况下,大量请求将落到后面的数据库上,可能会导致数据库崩溃。

因此,hotkey 很可能成为系统性能的瓶颈点,需要单独对其进行优化,以确保系统的高可用性和稳定性。

hotkey 的常见处理以及优化办法如下(这些方法可以配合起来使用):

  • 读写分离:主节点处理写请求,从节点处理读请求。
  • 使用 Redis Cluster:将热点数据分散存储在多个 Redis 节点上。
  • 二级缓存:hotkey 采用二级缓存的方式进行处理,将 hotkey 存放一份到 JVM 本地内存中(可以用 Caffeine)。

(5)慢查询

(6)内存碎片

6.Redis 生产问题

(1)缓存穿透

大量请求的 key 是不合理的,根本不存在于缓存中,也不存在于数据库中 。这就导致这些请求直接到了数据库上,根本没有经过缓存这一层,对数据库造成了巨大的压力,可能造成宕机

(2)缓存击穿

请求的 key 对应的是 热点数据 ,该数据 存在于数据库中,但不存在于缓存中(通常是因为缓存中的那份数据已经过期) 。这可能会导致瞬时大量的请求直接打到数据库上,对数据库造成了巨大的压力,造成宕机

(3)缓存雪崩

缓存在同一时间大面积的失效或缓存服务宕机,导致大量的请求都直接落到了数据库上,对数据库造成了巨大的压力,导致宕机

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度解析:AI大模型高效推理技术全览,掌握顶尖性能优化策略!

1 介绍 大型语言模型在人工智能领域中具有巨大的潜力 ,但推理过程中的禁止记忆和计算预算阻碍了其部署。 为了应对这些挑战,提出了许多针对LLMs的专业压缩方法,包括剪枝、知识传递、量化、紧凑的架构设计以及动态网络等。这些方法有助于减少…

219页PDF || 大模型技术引领行业变革:2024大模型典型示范应用案例集(附案例集下载)

大家好,今天给大家分享一本《2024大模型典型示范应用案例集》我已将这本案例集打包好了,包括市面上AI大模型各大白皮书、AGI大模型系统学习路线、AI大模型视频教程、实战学习,等录播视频免费分享出来,需要的小伙伴可以扫取。 引…

Nacos配置内容加密实现

一,背景 因为项目中安全检查的要求,需要将nacos配置的内容进行加密,所以需要实现将配置内容加密处理,这里引入nacos-aes-encryption-plugin插件来完成这一需求。 二,实现步骤 1, 重新编译nacos服务端 1.1 从githu…

海量数据处理商用短链接生成器平台 - 17

第五十八章 数据可视化ADS层-应用数据服务开发实战 第1集 数据可视化ADS层介绍和微服务整合ClickHouse项目 简介: 数据可视化ADS层介绍和微服务整合ClickHouse项目 数据分层 数据分层分层描述数据生成计算工具存储ODS原生数据,短链访问基本信息Sprin…

计算机的启动过程

通常搜索到的往往是 BIOS 按照“启动顺序”,把控制权转交给排在第一位的存储设备:硬盘。然后在硬盘里寻找主引导记录的分区,这个分区告诉电脑操作系统在哪里,并把操作系统被加载到内存中,然后你就能看到经典的启动界面…

HarmonyOS NEXT - 三方库axios的使用和封装

demo 地址: https://github.com/iotjin/JhHarmonyDemo 代码不定时更新,请前往github查看最新代码 在demo中这些组件和工具类都通过module实现了,具体可以参考HarmonyOS NEXT - 通过 module 模块化引用公共组件和utils HarmonyOS NEXT - 三方库axios的使用…

Matplotlib入门与进阶:数据可视化的强大工具

Matplotlib入门与进阶:数据可视化的强大工具 在当今数据驱动的世界中,数据可视化成为了数据分析的重要一环。数据可视化不仅能够帮助开发者理解和分析数据,还能使数据展示更具说服力。本文将详细介绍Python中的2D绘图库——Matplotlib。通过…

通过共享目录上传后门

本文来自无问社区,更多实战内容可前往查看http://www.wwlib.cn/index.php/artread/artid/13337.html 操作步骤 枚举目标主机开启的共享服务信息:10.0.0.6 smbclient -L //10.0.0.6 -U spotWARNING: The "syslog" option is deprecated Ente…

flink车联网项目前篇:数据开发(第66天)

系列文章目录 03_数据仓库开发 开发规范 1.1 数据库划分规范 1.2 表命名规范 1.3 表字段类型规范开发前准备 3.1 业务系统表 3.2 数据导入 04_维度主题相关表结构 1.1 dim_area - 城市字典表 1.2 dim_car_info - 车辆信息表 1.3 dim_car_vendor - 车队信息表 1.4 dim_date_wo…

虹科技术|优化始于数据:Baby-LIN设备如何高效存储总线数据?

记录汽车总线数据对于监控汽车电子控制单元(ECU)间的通信和诊断网络故障具有重要意义。通过记录测试时的总线数据,不仅可以监控产品是否按照预期运行,还能追踪特定错误或故障背后的原因,这对确保汽车产品质量和性能至关…

MySQL查询居然不区分大小写

MySQL查询居然不区分大小写 事故现场真实原因BINARY 关键字总结MySQL 为什么要这样设计呢?解决方案修改排序规则binary !!!!!懵逼了, MySQL 查询居然不区分大小写,第一次听到这么陌…

实验9 根据材料编程《汇编语言》- 王爽

1. 需求 编程:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串 welcome to masm! 2. 分析 (1)材料中提到,一个在屏幕上显示的字符,具有前景(字符色)和背景(底色)…

[000-01-030].第7节:Zookeeper工作原理

1.Zookeeper工作原理: 1.1.Zookeeper的工作机制 1.Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架;2.Zookeeper负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的…

来了,秋天的第一个POC

立秋就这么水灵灵地过了 又到了“秋天的第一杯奶茶”刷屏的时刻 而我们要追求的是“秋天的第一个POC” 做好变强的准备了吗 Yak POC编写,这一篇就够了 文章中指代的POC仅指使用 Yaklang 编程语言编写的POC 在此篇文章中就详细描述 Yaklang 语法的学习了&#x…

【昱合昇天窗】消防排烟天窗设计使用需注意问题

消防排烟天窗在设计和使用过程中,需要避免出现以下三个问题,以免影响其排烟效果和安全性。1、只关注价格 很多人在选择消防排烟天窗时,只关心天窗的价格,不重视天窗型号、配置选择是否满足厂房需求。这样做的坏处在于安装的天窗可…

还在画恐怖片?局部重绘,艺术再创造 —— Stable diffusion inPainting功能详解与实战指南

前言 在AI绘画的世界里,我们常常面临这样的困境:一幅作品,除了手部姿势、面部表情其他都很完美;这时候,如果要重新生成整幅画,不仅效率低下,而且可能会破坏原本满意的部分。幸好,St…

JAVA毕业设计|(免费)ssm视康眼镜网店销售系统的包含文档代码讲解

收藏点赞不迷路 关注作者有好处 编号:ssm538 ssm视康眼镜网店销售系统的 开发语言:Java 数据库:MySQL 技术:SpringSpringMVCMyBatisVue 工具:IDEA/Ecilpse、Navicat、Maven 文末获取源码 1.系统展示 2.万字文档展示 …

为什么MySql使用B+树

mysql索引为什么选择B树? 在回答这个问题之前,得先了解一个概念,页的概念。页是InnoDB中数据管理的最小单位。当我们查询数据时,其是以页为单位,将磁盘中的数据加载到缓冲池中的。同理,更新数据也是以页为…

数据库实验一 创建数据库

一.实验目的 1.学会数据表的创建; 2.加深对表间关系的理解; 3.理解数据库中数据的简单查询方法和应用。 二. 实验内容 1.题目要求 给定一个实际问题,实际应用问题的模式设计中至少要包括3个基本表。应用问题是供应商给工程供…

被嫌弃的35岁程序员,竟找到了职业的新出路:PMP项目管理

35岁,本应是事业发展的高峰期。更多听到的却是35岁职场天花板,特别是IT从业者,35岁就好像是一道迈不过的坎:多年的工作经验,在35岁的生理年龄面前,一文不值。 IT从业者若想安然度过“35岁危机”&#xff0…