专栏首页腾讯NEXT学位干货 | 认识数据库

干货 | 认识数据库

以前对数据库的了解,大概就是一个存放数据的地方,可进行增删查改,更多的就…慢慢学吧。

1

数据库事务

1.1

事务是什么

所谓事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位。

一个数据库事务通常包含了一个序列的对数据库的读/写操作。它的存在包含有以下两个目的:

  • 为数据库操作序列提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
  • 当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。

当事务被提交给了 DBMS(数据库管理系统),则 DBMS(数据库管理系统)需要确保该事务中的所有操作都成功完成且其结果被永久保存在数据库中,如果事务中有的操作没有成功完成,则事务中的所有操作都需要被回滚,回到事务执行前的状态;同时,该事务对数据库或者其他事务的执行无影响,所有的事务都好像在独立的运行。

1.2

ACID的事务

并非任意的对数据库的操作序列都是数据库事务。数据库事务拥有以下四个特性,习惯上被称之为ACID特性。

原子性(Atomicity) 事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。

一个事务是不可分割的,事务中的任何一条SQL执行失败,已经执行成功的语句也必须撤销,状态回退到执行事务之前。

一致性(Consistency) 事务应确保数据库的状态从一个一致状态转变为另一个一致状态。例如银行转账,保证事务结束后总数量不变。

一致状态的含义是数据库中的数据应满足完整性约束,事务开始和结束之间的中间状态不会被其他事务看到。

隔离性(Isolation) 多个事务并发执行时,一个事务的执行不应影响其他事务的执行。

持久性(Durability) 已被提交的事务对数据库的修改应该永久保存在数据库中。

一般来说,事务的 ACID 由 RDBMS 来实现的,RDBMS 采用日志来保证事务的原子性,一致性,持久性。采用锁的机制来实现事务的隔离性。

1.3

事务的隔离级别

在事务并发操作时,可能出现的问题有:

  • 脏读:事务A修改了一个数据,但未提交,事务B读到了事务A未提交的更新结果,如果事务A提交失败,事务B读到的就是脏数据。
  • 不可重复读:在同一个事务中,对于同一份数据读取到的结果不一致。比如,事务B在事务A提交前读到的结果,和提交后读到的结果可能不同。不可重复读出现的原因就是事务并发修改记录,要避免这种情况,最简单的方法就是对要修改的记录加锁,这回导致锁竞争加剧,影响性能。另一种方法是通过 MVCC 可以在无锁的情况下,避免不可重复读。
  • 幻读:在同一个事务中,同一个查询多次返回的结果不一致。事务A新增了一条记录,事务B在事务A提交前后各执行了一次查询操作,发现后一次比前一次多了一条记录。幻读是由于并发事务增加记录导致的,这个不能像不可重复读通过记录加锁解决,因为对于新增的记录根本无法加锁。需要将事务串行化,才能避免幻读。

ANSI/ISO SQL定义的标准隔离级别有四种,从高到底依次为:可序列化(Serializable)、可重复读(Repeatable reads)、提交读(Read committed)、未提交读(Read uncommitted)。

未提交读(Read uncommitted) 最低的隔离级别,什么都不需要做,允许脏读,也就是可能读取到其他会话中未提交事务修改的数据。所有的并发事务问题都会发生。

提交读(Read committed) 只有在事务提交后,其更新结果才会被其他事务看见。可以解决脏读问题。Oracle 等多数数据库默认都是该级别 (不重复读)。

可重复读(Repeatable reads) 在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。MySQL/InnoDB 默认级别,可以解决脏读、不可重复读。

可序列化(Serializable) 事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。

2

数据库索引

2.1

什么是索引

数据库索引是怎样提升性能的?使用索引的全部意义就是通过缩小一张表中需要查询的记录/行的数目来加快搜索的速度。可以把数据库索引比作书的目录索引,当我们需要在一本动物百科里寻找秋田犬的时候,可以通过目录快速定位到具体的位置。

数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。

2.2

索引是什么

一个索引是存储的表中一个特定列的值数据结构(最常见的是B-Tree)。索引是在表的列上创建。所以,要记住的关键点是索引包含一个表中列的值,并且这些值存储在一个数据结构中。

数据库管理系统(RDBMS)通常决定索引应该用哪些数据结构。但是,在某些情况下,你在创建索引时可以指定索引要使用的数据结构。

B-Tree 索引 B-Tree 是最常用的用于索引的数据结构。因为它们是时间复杂度低, 查找、删除、插入操作都可以可以在对数时间内完成。另外一个重要原因存储在 B-Tree 中的数据是有序的。

哈希索引

哈希表是另外一种你可能看到用作索引的数据结构——这些索引通常被称为哈希索引。使用哈希索引的原因是,在寻找值时哈希表效率极高。

哈系索引的工作方式是将列的值作为索引的键值(key),和键值相对应实际的值(value)是指向该表中相应行的指针。所以,如果使用哈希索引,对于比较字符串是否相等的查询能够极快的检索出的值。

哈希表是无顺的数据结构,对于很多类型的查询语句(范围查询)哈希索引都无能为力。哈希表的键值映射也暗示其键的存储是无序的。这就是为什么哈希索引通常不是数据库索引的默认数据结构——因为在作为索引的数据结构时,其不像B-Tree那么灵活。

R-Tree 使用 R-Tree 作为数据结构的索引通常用来为空间问题提供帮助。例如,一个查询要求“查询出所有距离一公里之内的超市”,如果数据库表使用 R-Tree 索引,这类查询的效率将会提高。

位图索引 位图索引(bitmap index)适合放在包含布尔值(true 和 false)的列上,但是这些值(表示true或false的值)的许多实例-基本上都是选择性(selectivity)低的列。

2.3

合理使用索引

数据库索引能提升性能,那当然它也会有一些缺点:

  1. 索引会占用空间 - 你的表越大,索引占用的空间越大。
  2. 性能损失(主要值更新操作),当你在表中添加、删除或者更新行数据的时候,在索引中也会有相同的操作。记住:建立在某列(或多列)索引需要保存该列最新的数据。

基本原则是只如果表中某列在查询过程中使用的非常频繁,那就在该列上创建索引。

2.4

索引类型

根据数据库的功能,可以在数据库设计器中创建三种索引:唯一索引、主键索引和聚集索引。

唯一索引 唯一索引是不允许其中任何两行具有相同索引值的索引。

当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。

主键索引 数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。

在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。

当表中只有一个主键时,它是唯一的索引;当表中有多个主键时,称为复合主键,复合主键联合保证唯一索引。

主键索引和唯一索引的区别:

  • 主键是一种约束,唯一索引是一种索引,两者在本质上是不同的
  • 主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键
  • 唯一性索引列允许空值,而主键列不允许为空值
  • 主键列在创建时,已经默认为非空值 + 唯一索引
  • 主键可以被其他表引用为外键,而唯一索引不能
  • 一个表最多只能创建一个主键,但可以创建多个唯一索引
  • 主键更适合那些不容易更改的唯一标识,如自动递增列、身份证号等

聚集索引 在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。

如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。

3

参考

  • 维基百科-数据库事务
  • 数据库事务的四大特性(ACID)以及事务的隔离级别
  • 知乎-如何理解数据库事务中的一致性的概念?
  • 维基百科-数据库索引
  • 数据库索引到底是什么,是怎样工作的?
  • 主键索引和唯一索引的区别

THE END

结束语关于数据库的事务和索引,也算是比较基础的内容了,但对本骚年来说也是不大了解。一下子学这么多,有点消化不过来,本节就先介绍数据库事务和索引,文章大多数都是参考来的内容,很多也需要好好理解。

文章来源:腾讯工程师 王贝珊

本文分享自微信公众号 - 腾讯NEXT学院(Next_Academy),作者:爱学习的小N

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python 工匠:让函数返回结果的技巧

    序言 ? 毫无疑问,函数是 Python 语言里最重要的概念之一。在编程时,我们将真实世界里的大问题分解为小问题,然后通过一个个函数交出答案。函数即是重复代码...

    腾讯NEXT学位
  • Python 工匠:善用变量来改善代码质量

    编程某种意义上是一门『手艺』,因为优雅而高效的代码,就如同完美的手工艺品一样让人赏心悦目。

    腾讯NEXT学位
  • 小游戏内存优化与性能优化

    ? | 导语 听说你的小游戏内存超标?进来了解一下吧。 本文主要跟大家一起来探讨一下Cocos Creator小游戏开发过程中内存优化、性能优化和包体优化。 ...

    腾讯NEXT学位
  • Java 面试知识点解析(六)——数据库篇

    我没有三颗心脏
  • Java 面试知识点解析(六)——数据库篇

    在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Jav...

    我没有三颗心脏
  • mysql优化:覆盖索引(延迟关联)

    上周新系统改版上线,上线第二天就出现了较多的线上慢sql查询,紧接着dba 给出了定位及解决方案,这里较多的是使用延迟关联去优化。 而我对于这个延迟关联也是...

    一枝花算不算浪漫
  • Mysql索引

    建立索引也有缺点,在对表进行INSERT、UPDATE、DELETE时要维护索引文件,经常更新的表就不需要建立索引了

    晚上没宵夜
  • 单机数据库优化的一些实践

    数据库优化有很多可以讲,按照支撑的数据量来分可以分为两个阶段:单机数据库和分库分表,前者一般可以支撑500W或者10G以内的数据,超过这个值则需要考虑分库分表。...

    哲洛不闹
  • 图解:基于B+树索引结构,MySQL可以这么优化

    标志这个sql语句被分为几个(行数)独立的sql执行,执行顺序依照(1)从大到小(2)从上到下 依次排列执行

    你好戴先生
  • Mysql的SQL性能优化指北

    在一次和技术大佬的聊天中被问到,平时我是怎么做Mysql的优化的?在这个问题上我只回答出了几点,感觉回答的不够完美,所以我打算整理一次SQL的优化问题。

    暴走大数据

扫码关注云+社区

领取腾讯云代金券