数据库
什么是mysql
是一种关系型数据库,也是数据库管理系统
术语
主键
主键是唯一的,数据库表只能包含一个主键
外键
用于关联两个表
索引
索引是对数据库表中一列或多列的值进行排序的一种结构
优点:
- 保证数据的唯一性
- 提高查询速度
- 加快表与表之间的连接
- 分组和排序时,加快速度
缺点:
- 更新数据时效率低,因为要同时更新索引
- 创建索引和维护索引需要时间成本
- 创建索引和维护索引需要空间成本
视图
是虚拟的表,与包含数据的表不一样,视图包含使用时动态检索数据的查询,不包含任何列或数据
悲观锁和乐观锁
悲观锁:
- select … for update操作来实现悲观锁,获取select的行锁
- 优先获取锁,再进行业务处理,一锁二查三更新
- 举例:行锁,表锁,读锁和写锁,synchronized
- 适合经常产生冲突的情况
乐观锁:
实现:版本号和CAS算法
CAS算法
- compare and swap(比较与交换),是一种有名的无锁算法。
- 涉及到三个操作数1.需要读写的地址 V 2.进行比较的旧值 A 3.拟写入的新值 B
- 当且仅当 V 的值等于 A时,CAS通过原子方式用新值B来更新V的值,否则不会执行任何操作
- ABA问题:一个线程one从内存位置V中取出A,这时候另一个线程two也从内存中取出A,并且two进行了一些操作变成了B,然后two又将V位置的数据变成A,这时候线程one进行CAS操作发现内存中仍然是A,然后one操作成功
- 缺点:ABA问题;改进:版本号
版本号:
- 提交版本必须大于记录当前版本才能执行更新
- 若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。
在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的
如何保证线程安全
冲突检测和数据更新
共享锁
共享锁又称 读锁 read lock ,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。
数据库优化
SQL语句优化
having、where、避免临时表、避免使用in not in or having、避免distinct耗费时间的排序操作,模糊匹配,临时表,减少重复工作
数据库范式
- 第一范式:列的原子性,不能再拆分为列
- 第二范式:1NF,没有包含主键的列必须完全依赖于主键
- 第三范式:首先2NF,非主键列必须直接依赖主键,不存在传递依赖
索引的优化
- 独立的列:索引不能是表达式的一部分
- 索引列的顺序:选择性强的索引列放在前面
- 前缀索引:对于varchar类型的列,使用前缀索引
- 覆盖索引:覆盖所有要查询的字段的值
优化数据访问
- 减少请求的数据量
- 只返回必要的列
- 返回必要的行
- 缓存重复查询的数据
- 减少服务器扫描的行数:使用索引来覆盖查询
查询性能优化
- 使用Expalin分析
- id:查询的标识符
- key:使用的索引
- select_type:使用select的类型
- type:连接使用了哪种类别
- rows:使用的行数
- 慢查询
- long_query怎么解决 ?设置参数,开启慢日志功能,得到耗时超过一定时间的sql
B树和B+树
B+树
B+树索引
- 主索引
- B+树叶子节点data域记录完整的数据记录,这种叫做聚簇索引
- 因为无法把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引
- 辅助索引
- 辅助索引的叶子节点的data域记录着主键的值。
- 使用辅助索引进行查找,先获取主键值,再到主索引进行查找
原理
- 基于B树和叶子节点顺序访问指针进行实现
- 所有关键字都出现在叶子结点的链表中。且链表中的关键字恰好是有序的;
- 不可能在非叶子结点命中;非叶子节点作为一个索引
B树
- 1.所有非叶子结点至多拥有两个儿子(Left和Right);
- 2.所有结点存储一个关键字;
- 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树
与红黑树的比较:为什么使用B+树实现索引
- 平衡树查找复杂度等于树高,红黑树的树高太高而引起I/O操作频繁,导致效率低下
- 一次I/O读入一块,一块的大小就是b+树叶子节点的大小,每次读入一个完整的节点,所以是一个树高
B+树和B树区别
- B+树所有查询都要查找到叶子节点,查询性能稳定。
- B+树所有叶子节点形成有序链表,便于范围查询
数据库连接池的作用
- 维护一定数量的连接,减少创建连接的时间
- 更快的响应时间
- 统一的管理
mysql高并发
聚集索引和非聚集索引区别
- 聚集索引,数据按索引顺序存储,子结点存储真实的物理数据 。索引的叶节点就是数据节点
- 非聚集索引,叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。
复制
主从复制
- 含义:建立一个和主数据库完全一样的数据库环境
- 线程
- binlog线程:负责将主服务器上的数据更改写入二进制日志中
- 从库I/O线程:负责从主服务器上读取二进制日志,并写入从服务器的重放日志(Replay log)中
- 从库SQL线程:负责读取重放日志并重放其中的SQL语句
- 原理:
- 1.数据库有个bin-log二进制文件,记录了所有sql语句。
- 2.我们的目标就是把主数据库的bin-log文件的sql语句复制过来。
- 3.让其在从数据的relay-log重做日志文件中再执行一次这些sql语句即可。
- 好处:
- 1、做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。
- 2.读写分离,使数据库能支撑更大的并发。部分报表sql语句非常的慢,导致锁表,影响前台服务。如果前台使用master,报表使用slave,那么报表sql将不会造成前台锁,保证了前台速度。
读写分离
- 概念:读从库,写主库
- 提高性能的原因
- 主从数据库负责各自的读和写,极大程度缓解了锁的争用
- 从服务器可以使用MyISAM,提升查询性能以及节约系统开销
- 增加冗余,提高可用性
- 冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性。
数据库事务的四个特性
- 原子性 整个事务要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在中间某个过程中发生错误,会被回滚到开始的状态
- 一致性 在事务开始之前,和在事务执行完成后,数据库的完整性约束没有被破坏
- 隔离性 多个用户访问数据库时,数据库为每一个用户开启一个事务,事务之间互不干扰。
- 持久性 在事务完成以后,该事务所对数据库做的更改会持久保存在数据库中,并不会被回滚
防止SQL注入
- 原理:利用数据库对特殊标识符的解析强行从页面向后台传入
- 原因:传入的参数与系统的SQL拼接成了合法的SQL而导致的
- 防止SQL注入
- 使用PreparedStatement(预处理执行语句),它内置了处理SQL注入的能力,可以对SQL语句进行查询参数化,只要使用setString方法传值即可
- 采用正则表达式将包含有单引号(')、分号(;)、注释符号(--)的语句给替换掉来防止SQL注入
- Mybatis下注入防范:Mybatis是支持定制化SQL、存储过程以及高级映射的优秀的持久层框架,几乎避免了所有的JDBC代码和手动设置参数以及获取结果集。
- 使用Hibernate框架的SQL注入防范