mysql的两种存储引擎和特点,区别和底层
两种数据结构都是用的B+树
原因:B+树的非叶子节点不存储数据,只有叶子节点才存储数据,而且B+树的叶子节点之间会有指针相连,也方便进行范围查找
1. MyISAM(非聚集索引)
- 不支持事务,但是操作时原子性的
- 不支持外键,支持表锁,每次操作都是锁住整张表
- MyISAM表格可以被压缩,而且它们
支持全文搜索
表锁:操作时,会锁定整个表。开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低。
行锁:操作时,会锁定当前操作的表的某些行。开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高。
页锁:操作时,会锁定当前操作的表的某些页。开销和加锁速度介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般。
2. InnoDB(聚集索引)
- 支持外键
- 支持行锁
- 不支持全文搜素
MyISAM:
优点:查询数据相对较快,适合大量的select,可以全文索引。
缺点:不支持事务,不支持外键,并发量较小,不适合大量update
InnoDB:
优点:支持事务,支持外键,并发量较大,适合大量update
缺点:查询数据相对较快,不适合大量的select
3 MySQL 中常见的索引
主键索引:数据列不允许重复,不允许null,一个表只能有一个主键
普通索引:没有什么限制,允许在定义索引的列中插入重复值和null值,一个表允许多个列创建
唯一索引:索引列中的值必须是唯一的,但是允许null值。
4 mysql中事务的特点以及事务带来的特点
原子性:要么都提交,要么都不提交
一致性:事务前后数据的完整性必须保持一致
持久性:事务一旦被提交,它对数据库的改变是永久性的
隔离性:多个用户访问数据库时,多个并发事务之间要相互隔离
- 脏读:指一个线程中的事务读取到了另外一个线程中未提交的数据。
- 不可重复读:指一个线程中的事务读取到了另外一个线程中提交的update的数据。
- 幻读(虚读):指一个线程中的事务读取到了另外一个线程中提交的insert的数据。
5 数据库的锁的分类以及死锁和解决
乐观锁, 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。
悲观锁,顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
数据库悲观锁和乐观锁的原理和应用场景分别有什么?
悲观锁,先获取锁,再进行业务操作,一般就是利用类似 SELECT … FOR UPDATE 这样的语句,对数据加锁,避免其他事务意外修改数据。当数据库执行SELECT … FOR UPDATE时会获取被select中的数据行的行锁,select for update获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用。
乐观锁,先进行业务操作,只在最后实际更新数据时进行检查数据是否被更新过。Java 并发包中的 AtomicFieldUpdater 类似,也是利用 CAS 机制,并不会对数据加锁,而是通过对比数据的时间戳或者版本号,来实现乐观锁需要的版本判断。
死锁的定义:二个或者二个以上的进程在执行时候,因为争夺资源造成相互等待的现象,进程一直处于等待中,无法得到释放。
造成死锁的四个条件
互斥条件
请求和保持条件(在所有进程运行之前,一次性申请运行过程中所需的全部资源,或者在每个进程提出新的资源申请前,释放它索占的资源)
不可剥夺条件(允许对资源进行抢夺,一个进程进一步资源请求被拒绝,则该进程必须释放它最初占有的资源,如果有必要,可以再次请求这些资源和另外资源)
循环等待条件(对系统所有资源进行线性排序并赋予不同序号,这样我们在规定进程在申请资源时必须按照序号递增的顺序进行资源的申请)
数据库的三范式和数据库的调优
数据库的三范式:每一列属性都是不可再分的属性值
属性完全依赖于主键
属性不依赖于其他非主属性,属性直接依赖于主键
数据库的调优
- 选择最实用的字段属性
- 使用连接join来代替子查询
- 创建适当的索引
- 使用联合(UNION)来代替手动创建的临时表
- select*少用 用具体的查询语句
- 允许适当的冗余
注意事项:所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。