事务 事务是由 MySQL 的引擎来实现,常见的 InnoDB 引擎它是支持事务的 并不是所有的引擎都能支持事务,比如 MySQL 原生的 MyISAM 引擎就不支持事务
特性 具体特性
原子性:一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节;事务在执行过程中发生错误,会被回滚到事务开始前的状态 一致性:事务操作前和操作后,数据满足完整性约束,数据库保持一致性状态 隔离性:允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失 如何保证特性?
持久性是通过 redo log (重做日志)来保证的 原子性是通过 undo log(回滚日志) 来保证的 隔离性是通过 MVCC(多版本并发控制) 或锁机制来保证的 一致性则是通过持久性+原子性+隔离性来保证 隔离级别 MySQL服务端允许多个客户端连接,意味着 MySQL 会出现同时处理多个事务的情况 问题: 脏读:如果一个事务「读到」了另一个「未提交事务修改过的数据」 事务 A 是还没提交事务的,也就是它随时可能发生回滚操作,被读 不可重复读:一个事务内多次读取同一个数据,如果出现前后两次读到的数据不一样的情况 事务A两次读取过程中,事务B进行修改且提交 幻读:一个事务内多次查询某个符合查询条件的「记录数量」,如果出现前后两次查询到的记录数量不一样的情况 事务A两次读取过程中,事务B进行修改且提交 隔离级别 读未提交:一个事务还没提交时,它做的变更就能被其他事务看到 读提交:一个事务提交之后,它做的变更才能被其他事务看到 可重复读:一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,MySQL InnoDB 引擎的默认隔离级别 串行化:会对记录加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行 「可重复读」但是很大程度上避免幻读现象 针对快照读(普通 select 语句),通过 MVCC 方式解决了幻读,因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据,是查询不出来这条数据的 针对当前读(select … for update 等语句),是通过 next-key lock(记录锁+间隙锁)方式解决了幻读,当执行 select … for update 语句的时候,会加上 next-key lock,如果有其他事务在 next-key lock 锁范围内插入了一条记录,那这个插入语句就会被阻塞,无法成功插入 四种隔级别实现 「读未提交」可以读到未提交事务修改的数据,所以直接读取最新的数据就好 「串行化」通过加读写锁的方式来避免并行访问; 「读提交」和「可重复读」通过 Read View 来实现的,它们的区别在于创建 Read View 的时机不同,大家可以把 Read View 理解成一个数据快照,就像相机拍照那样,定格某一时刻的风景。「读提交」隔离级别是在「每个语句执行前」都会重新生成一个 Read View,而「可重复读」隔离级别是「启动事务时」生成一个 Read View,然后整个事务期间都在用这个 Read View 执行「开始事务」begin/start transaction 命令 执行了 begin/start transaction 命令后,并不代表事务启动了 只有在执行这个命令后,执行了第一条 select 语句,才是事务真正启动的时机 Read View在MVCC工作 Read View 有四个重要的字段: m_ids :在创建 Read View 时,当前数据库中「活跃事务」的事务 id 列表,注意是一个列表,“活跃事务”指的就是,启动了但还没提交的事务 min_trx_id :在创建 Read View 时,当前数据库中「活跃事务」中事务 id 最小的事务,也就是 m_ids 的最小值 max_trx_id :这个并不是 m_ids 的最大值,而是创建 Read View 时当前数据库中应该给下一个事务的 id 值,就是全局事务中最大的事务 id 值 + 1 creator_trx_id :创建该 Read View 的事务的事务 id InnoDB 存储引擎的数据库表,聚簇索引记录中包含下面两个隐藏列: trx_id:一个事务对某条聚簇索引记录进行改动时,会把该事务的事务 id 记录在 trx_id 隐藏列里 roll_pointer:每次对某条聚簇索引记录进行改动时,都会把旧版本的记录写入到 undo 日志中,这个隐藏列是个指针,指向每一个旧版本记录,于是就可以通过它找到修改前的记录 通过「版本链」控制并发事务访问同一个记录时的行为叫 MVCC(多版本并发控制) 可重复读和读提交如何工作 可重复读隔离级别是启动事务时生成一个 Read View,然后整个事务期间都在用这个 Read View 读提交隔离级别是在每次读取数据时,都会生成一个新的 Read View 日志 undo log(回滚日志):是 Innodb 存储引擎层生成的日志,实现了事务中的原子性,主要用于事务回滚和 MVCC...
MySQL查询过程 MySQL 的架构共分为两层:Server 层和存储引擎层
Server 层负责建立连接、分析和执行 SQL。主要包括连接器,查询缓存、解析器、预处理器、优化器、执行器等。另外,所有的内置函数(如日期、时间、数学和加密函数等)和所有跨存储引擎的功能(如存储过程、触发器、视图等。)都在 Server 层实现 存储引擎层负责数据的存储和提取。支持 InnoDB、MyISAM、Memory 等多个存储引擎,不同的存储引擎共用一个 Server 层。从 MySQL 5.5 版本开始, InnoDB 成为了 MySQL 的默认存储引擎。索引数据结构就是由存储引擎层实现,不同的存储引擎支持的索引类型也不相同,比如 InnoDB 支持索引类型是 B+树 ,且是默认使用,在数据表中创建的主键索引和二级索引默认使用的是 B+ 树索引 第一步:连接器 启动Mysql服务,连接 MySQL 服务
# -h 指定 MySQL 服务得 IP 地址,如果是连接本地的 MySQL服务,可以不用这个参数; # -u 指定用户名,管理员角色名为 root; # -p 指定密码,如果命令行中不填写密码(为了密码安全,建议不要在命令行写密码),就需要在交互对话里面输入密码 mysql -h$ip -u$user -p 查看 MySQL 服务被多少客户端连接
执行 show processlist 命令进行查看
MySQL 定义空闲连接的最大空闲时长,由 wait_timeout 参数控制的,如果空闲连接超过了这个时间,连接器就会自动将它断开
mysql> show variables like 'wait_timeout'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | wait_timeout | 28800 | +---------------+-------+ 1 row in set (0....
SQL基本使用 关系型数据库 数据库:保存用户数据
随着应用程序的功能越复杂,数据量越大,管理这些数据就成了大问题 读写文件并解析出数据需要大量重复代码; 从成千上万的数据中快速查询出指定数据需要复杂的逻辑 数据模型
层次模型:以“上下级”的层次关系来组织数据的一种方式,看起来就像一颗树 网状模型:每个数据节点和其他很多节点都连接起来,看起来就像很多城市之间的路网 关系模型:数据看作是一个二维表格,任何数据都可以通过行号+列号来唯一确定,看起来就是一个Excel表 常见数据类型
名称 类型 说明 INT 整型 4字节整数类型,范围约+/-21亿 BIGINT 长整型 8字节整数类型,范围约+/-922亿亿 REAL 浮点型 4字节浮点数,范围约+/-1038 DOUBLE 浮点型 8字节浮点数,范围约+/-10308 DECIMAL(M,N) 高精度小数 由用户指定精度的小数,例如,DECIMAL(20,10)表示一共20位,其中小数10位,通常用于财务计算 CHAR(N) 定长字符串 存储指定长度的字符串,例如,CHAR(100)总是存储100个字符的字符串 VARCHAR(N) 变长字符串 存储可变长度的字符串,例如,VARCHAR(100)可以存储0~100个字符的字符串 BOOLEAN 布尔类型 存储True或者False DATE 日期类型 存储日期,例如,2018-06-22 TIME 时间类型 存储时间,例如,12:20:59 DATETIME 日期和时间类型 存储日期+时间,例如,2018-06-22 12:20:59 SQL
结构化查询语言的缩写,用来访问和操作数据库系统。SQL语句既可以查询数据库中的数据,也可以添加、更新和删除数据库中的数据,还对数据库进行管理和维护操做 SQL语言关键字不区分大小写!!!但表名和列名不一定 MySQL本身只是一个SQL接口,内部包含多种数据引擎
InnoDB:一款支持事务的数据库引擎 MyISAM:MySQL早期默认数据库引擎,不支持事务 关系模型 表的每一行称为记录(Record),记录是一个逻辑意义上的数据。
表的每一列称为字段(Column),同一个表的每一行记录都拥有相同的若干字段。
主键
记录一旦插入到表中,主键最好不要再修改,因为主键是用来唯一定位记录的,修改了主键,会造成一系列的影响 主键的一个基本原则:不使用任何业务相关的字段作为主键,也不应该允许NULL 一般字段命名为id ,常见类型有 自增整数类型:数据库会在插入数据时自动为每一条记录分配一个自增整数,这样我们就完全不用担心主键重复,也不用自己预先生成主键 全局唯一GUID类型:也称UUID,使用一种全局唯一的字符串作为主键,类似8f55d96b-8acc-4636-8cb8-76bf8abc2f57。GUID算法通过网卡MAC地址、时间戳和随机数保证任意计算机在任意时间生成的字符串都是不同的 联合主键 通过多个字段唯一标识记录,即两个或更多的字段都设置为主键 外键
在students表中,通过class_id的字段,可以把数据与另一张表关联起来,这种列称为外键
定义外键约束,关系数据库可以保证无法插入无效的数据。即如果classes表不存在id=99的记录,students表就无法插入class_id=99的记录
外键并不是通过列名实现的,而是通过定义外键约束实现的:...