认识存储 &数据库|青训营

62 阅读9分钟

在当今信息化社会中,数据已经成为了一种重要的资源。随着互联网和移动互联网的快速发展,人们产生的数据量也越来越大,如何有效地管理和利用这些数据成为了摆在我们面前的一个严峻问题。而存储技术和数据库技术则是解决这一问题的重要手段之一。本文将介绍存储技术和数据库技术的基础知识,包括它们的概念、特点、分类等。

ACID

原子性(Atomicity):事务是数据库的逻辑工作单位, 事务中包括的诸操作要么都做,要么都不做(数据库日志和锁)

一致性(Consisency): 事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态

隔离性(Isolation):一个事务的执行不能被其他事务干扰(MVCC版本控制)

持久性(Durability):一个事务一旦提交,它对数据库中数据的改变就应该 是永久性的。

事物隔离级别

InnoDB默认隔离级别:可重复读

  • 读未提交(Read Uncommitted):在该隔离级别下,一个事务可以读取其他事务未提交的数据,可能导致脏读、不可重复读和幻读的情况。
  • 读已提交(Read Committed):在该隔离级别下,一个事务只能读取已经提交的数据,可以避免脏读,但仍有不可重复读和幻读的情况。
  • 可重复读(Repeatable Read):在该隔离级别下,一个事务在执行过程中所读取的数据不会被其他事务修改,但可能存在幻读的情况。
  • 串行化(Serializable):在该隔离级别下,每个事务都是独占的,不会有其他事务干扰,可以避免脏读、不可重复读和幻读的情况,但效率较低。
  • 脏读:是指一个事务读取到了另一个事务未提交的修改数据,这种情况下,如果另一个事务回滚了,那么当前事务读到的数据就是不正确的。不可重复度:是指一个事务读取同一数据多次,但是每次读取的结果不同。这是由于在读取之间,另一个事务修改了这个数据,导致读取的结果不同。幻读:是指一个事务读取到了不存在的数据,或者读取到了已经删除的数据,因为另一个事务在读取期间插入了数据或者删除了数据。这种情况对于数据的完整性和一致性造成了严重影响。

数据库引擎

innoDB(支持事物)、MyISAM(锁、索引、备份和迁移)、Memory(内存引擎)

数据库日志

redolog:重做、undolog:回滚、binlog:二进制

MySQL索引

  1. PRIMARY KEY 索引:是唯一索引,可以用来标识表中的每一行数据。
  2. UNIQUE 索引:是唯一索引,但不同于 PRIMARY KEY 索引,可以有空值。
  3. INDEX 索引:是普通索引,可以允许多个相同的值。
  4. FULLTEXT 索引:是全文索引,用于搜索关键字和短语。
  5. SPATIAL 索引:是空间索引,用于处理空间数据。

B+索引和Hash索引:B+ 索引的优点在于,它提供了快速查询的能力,同时还支持区间查询和排序。

数据库调优

创建索引、避免在索引上使用计算、调整where连接顺序(过滤掉最大数量记录)、使用where调换having、使用表的别名、避免使用游标、使用varchar替换char、用具体的字段代替*、update尽量不要更改全部、使用select into替代insert

慢查询优化:

  1. 定期清理无用索引:无用索引的存在会影响查询性能,因此需要定期清理无用索引。可以通过查询information_schema库中的表统计信息,找出未使用的索引并进行清理。
  2. 优化查询语句:优化查询语句可以改进查询性能。一般可以从以下几个方面入手:优化SQL语句结构、增加索引、避免使用复杂查询、减少重复查询等。

聚簇索引和非聚簇索引

  • 聚簇索引:将与索引放到了一块,找到索引也就找到了数据
  • 非聚簇索引:将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因

B+树索引

相邻叶子节点是通过指针连起来的,并且是关键字大小排序的。

数据库的锁机制

  1. 共享锁:允许多个事务同时对同一数据进行读取操作,但不允许写操作,保证数据的一致性。在事务读取数据时,会先申请共享锁,如果该数据未被排他锁占用,则可获取共享锁并进行读取,如果该数据被排他锁占用,则需要等待排他锁的释放才能获取共享锁。
  2. 排他锁:一次只允许一个事务对数据进行修改或删除操作,保证数据的完整性。在事务修改或删除数据时,会先申请排他锁,如果该数据未被其他锁占用,则可获取排他锁并进行修改或删除,如果该数据被其他锁占用,则需要等待其他锁的释放才能获取排他锁。
  3. 记录锁(Record Lock):仅锁定一行记录(如固定)间隙锁(Gap Lock):锁定一个范围,但不包含记录本身临键锁:锁定一个范围,并且锁定记录本身

主要有以下类型:

  1. 行级锁:锁定数据行,只对单行数据进行加锁,其他行数据不受影响,适用于高并发场景,但可能会增加锁冲突的概率和锁开销。
  2. 表级锁:锁定整张表,适用于并发量较小的场景,但可能会导致锁等待时间过长、锁冲突较多等问题。
  3. 页级锁:锁定数据页,每个数据页可以包含多行数据,对一页数据进行加锁,适用于中等并发量的场景,可以减少锁开销和锁冲突。
  4. 数据库级锁:锁定整个数据库,对整个数据库进行加锁,适用于并发量很小的场景,但可能会导致大量锁等待和锁冲突。

索引的优缺点

索引的优点:① 建立索引的列可以保证行的唯一性,生成唯一的rowId

② 建立索引可以有效缩短数据的检索时间

③ 建立索引可以加快表与表之间的连接

④ 为用来排序或者是分组的字段添加索引可以加快分组和排序顺序

索引的缺点:① 创建索引和维护索引需要时间成本,这个成本随着数据量的增加而加大

② 创建索引和维护索引需要空间成本,每一条索引都要占据数据库的物理存储空间,数据量越大,占用空间也越大(数据表占据的是数据库的数据空间)

③ 会降低表的增删改的效率,因为每次增删改索引需要进行动态维护,导致时间变长

缓存问题

缓存穿透:数据本来就不存在,但是疯狂请求;

缓存雪崩:大量key值在同一个时间段过期;

缓存击穿:大量查询集中于一个或者几个key,突然这个key过期了;

CAS实现乐观锁

CAS 算法是一种原子操作,可以在不使用锁的情况下更新共享变量。它通过比较内存中的值与预期值,如果相等则更新,否则不更新。CAS 的操作过程可以分为三个步骤:

  1. 读取共享变量的当前值;
  2. 比较共享变量的当前值与预期值;
  3. 如果相等,则更新共享变量的值,否则不更新。

在 MySQL 中实现乐观锁通常可以通过以下步骤:

  1. 在表中添加一个版本号(version)字段,用于记录每次修改的版本号;
  2. 在更新数据时,通过查询当前版本号是否与预期版本号相等来判断是否有其他并发事务修改了数据;
  3. 如果版本号相等,则执行更新操作并将版本号加 1,否则返回更新失败。

MVCC实现事物隔离

在MVCC中,每个数据行都有一个版本号或时间戳。当一个事务开始时,它会读取该时刻的数据库状态,并在执行期间只看到在该时刻之前提交的版本。如果其他事务在这个事务执行期间修改了同一行数据,那么这个事务会看到该行的旧版本,而不会看到其他事务修改后的新版本。

在实现MVCC时,需要考虑以下几个方面:

  1. 版本的创建和维护:每个数据行需要创建多个版本,并在事务提交时删除旧版本。同时,需要维护每个版本的时间戳或版本号,以便事务可以读取正确的版本。
  2. 事务的启动和提交:在事务启动时,需要记录该事务的开始时间戳或版本号。在事务提交时,需要删除该事务创建的所有版本,并更新其他事务可以看到的版本号。
  3. 并发控制:为了保证事务的隔离性,需要对并发访问进行控制。通常使用锁或CAS(比较-交换)操作来控制并发访问。

MySQL的QPS从1-10000变化:

  1. 当QPS从1到10时,MySQL的性能变化不太明显。这是因为MySQL的默认配置可以轻松处理这个级别的负载。
  2. 当QPS从10到100时,MySQL的性能开始有所下降。这是因为随着查询数量的增加,MySQL需要处理更多的连接和查询请求,可能会出现性能瓶颈。
  3. 当QPS从100到1000时,MySQL的性能下降更为明显。这是因为MySQL需要处理更多的连接和查询请求,可能会出现锁竞争、磁盘I/O瓶颈等问题,需要对MySQL的配置和硬件进行优化。
  4. 当QPS从1000到10000时,MySQL的性能可能会达到极限。这是因为MySQL需要处理大量的连接和查询请求,可能会出现CPU、内存、磁盘等多个方面的瓶颈,需要对MySQL的配置和硬件进行深度优化。