1.事务的四大特性
数据库事务: 事物就是对一个数据库操作的序列,是一个不可分割的工作单位
ACID特性
- 原子性 Atomicity:事物
要么全部完成,要么全部取消
,如果事务崩溃,状态回到事务初始状态(事务回滚) - 隔离性 Isolation:通常来说,一个事务所做的修改在最终提交之前,对其它事务是不可见的。关于事务的隔离性,数据库提供了多种隔离级别。
- 持久性 Durability:事务一旦提交,不管(崩溃或错误),数据修改永久存储在数据库中
- 一致性 Consistency:事务执行之前和执行之后都必须处于一致性状态。
2. 事务的隔离级别
SQL标准定义了4类隔离级别
- Read Uncommited
读未提交
所有事务都可以查看到其他未提交事务的执行结果 - Read Committed(RC)
读已提交
事务只能看到已经提交事务所做的变更 - Repeatable Read(RR)
可重复读
确保同一事务的多个实例在并发读取数据时会看到相同的数据行 - Serializable
可串行化
完全串行化读,每次读都需要获得表级共享锁,读写相互阻塞
mysql的默认隔离级别为 可重复读
并发事务的问题
[1.]脏读
一个事务A读取了另一个事务B未提交的数据
[2.]不可重复读
在一个事务里,某个数据被读取了两次,读出来的数据不一致(修改)
[3.]幻读
在相同一个事务,按相同的查询条件读取数据,发现其他事务操作之后的新数据(新增、删除)
3. 索引
建立索引的目的是加快对表中记录的查找或排序
3.1索引的优点
- 在设计数据库时,通过创建一个唯一索引,能够在索引和信息之间形成一对一的映射式的对应关系
- 能提高数据的搜索及检索速度
- 能够加快表与表之间的连接速度
- 在信息检索过程中,若使用分组及排序子句进行时,通过建立索引能有效的减少检索过程中所需的分组及排序时间,提高检索效率
- 建立索引之后,在信息查询过程中可以使用优化隐藏器
3.2 索引的缺点
- 数据库中创建的索引需要占用一定的物理
存储空间
- 在数据库建立过程中,需花费较多的时间去建立并维护索引
- 在对表中的数据进行修改时,例如对其进行增加、删除或者是修改操作时,索引还需要进行动态的维护
3.3 索引的分类
-
唯一索引
任意两行的索引值
不能相同
create unique index indexname on 表名(列名(length))
// 创建索引
或者alter 表名 add index [indexname] on (列名(length))
// 修改表结构 -
主键索引
创建表时,主键自动创建主键索引,该索引要求主键中每个值都唯一primary key
-
组合索引
alter table 表名 add index 索引名(列名1,列名2,......)
-
聚集索引
一个表只能包含一个聚集索引;在聚集索引中,表中数据行的物理顺序和键值的索引(逻辑)顺序相同
将数据存储和索引放在一起,找到索引就能找到数据,文件根据对应字段排序存储,索引文件无重复
排序存储
- 索引列
基于数据库表中的单列或多列创建索引;多列索引可以区分其中一列可能有相同值的行
3.4 索引失效
3.5 索引设计原则
4.索引的数据结构
目前大部分数据库系统和文件系统都采用B树或B+树作为索引结构
4.1 B树
定义一个数据记录为一个二元组[key,data],不同的数据记录,key值不同
参考博客
- 每个非叶子节点由n-1个key和n个指针组成,其中d<=n<=2d(d是B树的度)
4.2 B+树
区别:
- 叶子节点存放数据,非叶子节点(内节点)存放指针索引
优点:
2. 所有的查询都要经过叶子节点,查询性稳定
3. 所有的叶子节点升序排列,形成一个有序链表,便于查找
4. 单一节点存储的元素更多,IO操作次数更少
B+Tree的每个叶子节点增加一个指向相邻叶子节点的指针
博客
5.InnoDB和MyISAM区别
- 存储结构
- MyISAM:每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。 .frm文件存储表定义。数据文件的扩展名为.MYD(MYD)。索引文件的扩展名是.MYI(MYIndex)
- InnoDB:所在的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB
-
存储空间
MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引
-
事务支持
MyISAM:强调的是性能,每次查询具有原子性,其执行速度比Innodb类型更快,但是不提供事物支持。
InnoDB:提供事务支持,外部键等高级数据库功能。具有事务(commit)、回滚(rollback)和崩溃修复能力(crach recovery capabilities)的事务安全(transaction-safe ACID compliant)型表
- CURD操作
MyISAM: 如果执行大量的select, MyISAM是更好的选择。(因为没有支持行级锁),在增删的时候需要锁定整个表格,效率会低一些。相关的是innoDB支持行级锁,删除插入的时候只需要锁定该行就行,效率较高。
InnoDB:如果你的数据执行大量的insert或update,出于性能方面的考虑,应该使用InnoDB表。Delete从性能上Innodb更优,但delete from table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate table这个命令
- 外键
MyISAM: 不支持
InoDB:支持
6. drop delete truncate区别
- drop(DDL语句):删除表,释放空间(依赖、索引、触发器)
drop table 表名
- delete(DML语句):删除表中数据行,并且将该行的删除操作作为事务记录在日志中,方便事务回滚
- truncate(DDL语句):清空表,删除内容、释放空间、但不删除定义(数据结构)
执行速度:drop> truncate > delete
7.DML和DDL的区别
DML(Data Manipulation Language):数据操纵语言,SQL处理数据等操作
select、update、delete、insert、merge
DDL(Data Definition Language):数据定义语言,用于定义和管理SQL数据库中的某些对象
create、alter、drop、truncate、comment、grant、revoke
区别:
- DML 可以手动控制事务的开启,提交和回滚
- DDL是隐形提交,不能回滚
8. 连接
- inner join:内连接,获取两个表中字段匹配的记录
- left join :左连接,获取左表中所有记录,即使右表没有对应匹配的记录
- right join右连接,获取右表中所有记录
9.where 、having 、on的区别
执行顺序:on>where>聚合函数>having
- 两个表连接时,使用
on
where
作用在对查询结果之前,将不符合where条件的行过滤掉,条件中不能包含聚合函数having
筛选满足条件的组,限制返回的结果集;即在分组之后过滤数据,条件中包含聚合函数
如:select deptno,sum(sal) from emp where sal>1200 group by deptno having sum(sal)>8500 order by deptno
10.查询速度慢如何解决
慢查询日志 用于记录响应时间超过阈值的语句,指运行时间超过long_query_time值的sql
- 查看慢查询是否开启
show variables like ‘%slow_query_log%’;
- 开启慢查询
set global slow_query_log=1;
- 查看慢查询默认时间
show variables like ‘long_query_time’;
- 修改慢查询时间
set global long_query_time=3;
- 设置慢查询存储的方式
set globle log_output = file;
、默认是none;table存储在mysql库下的slow_log表中
11. 表中数据结构的区别
- int(10) 、char(10) 、varchar(10)的区别
int(10)
:整数类型,10表示数据的长度
char(10)
:字符串,不可变,10表示存储字符大小;10位固定字符串,不足补空格 最多10个字符
varchar(10)
:可变,10表示存储字符大小;10位可变字符串,不足补空格 最多10个字符
- char的存取速度比varchar更快,长度固定方便存储查找
- char的存储方式是,对英文字符(ASCII)占用1个字节,对一个汉字占用两个字节;而varchar的存储方式是,对每个英文字符占用2个字节,汉字也占用2个字节
- char(10)表示存储定长的10个字符,不足10个就用空格补齐,占用更多的存储空间,而varchar(10)表示存储10个变长的字符,存储多少个就是多少个,空格也按一个字符存储,这一点是和char(10)的空格不同的,char(10)的空格表示占位不算一个字符
- int(10) int(11)有啥区别
int10和int11只是显示的长度不同,在计算机中都是占4个字节,32位
12.数据库的三大范式
1NF:字段不可分,每个字段是原子级别的
2NF:有主键,非主键字段依赖主键,ID字段就是主键,它能表示这一条数据是唯一的
3NF:非主键字段不能相互依赖
13.sql语句
加行号的使用规则:@rowNum = num 声明一个叫rowNum的变量并赋值为num
-
取出一个月内的id分组
-
取一个年级中每个班级年龄最小的同学名字
-
成绩表输出前三名,最后三名的成绩
select * from score表 where 排名<=3 order by scores desc
-
拷贝A表至B表
select * into B from A
// A,B表的结构相同 -
查询每门科目都大于80分的学生名字
select name from (select name,min(score) from studetent group by name having min(score>80) stu
-
筛选出每个小时的记录
-
聚合函数
avg count max min sum
-
一个数据库,查询重复次数
select count(*) ,column1.... from table1 group by column1....having count(*)>1
count(*)
重复的次数 -
查询总成绩最高人的姓名
-
user表中在一个时间段内登陆三次的用户id
-
limit的用法
14.mysql日志查询
- 首先输入
show variables like 'log'
查看日志是否开启 - 若日志没有开启,查看mysql服务的启动配置文件位置
- 关闭mysql服务,打开my.ini配置文件,添加变量log=E:/mysql_log.txt,然后启动mysql服务
- 重新登录mysql,查询表,此时所有操作都被记录在E:/mysql_log.txt文件中
15.主键、外键、索引
- 主键
关系型数据库中一条记录有若干属性,若某个
属性组
能唯一标识一条记录,该属性组就可以成为一个主键
- 学生表(学号,姓名,年龄,班级…):学号是唯一的,学号就是主键
- 成绩表(学号,课程号,成绩):学号不是唯一标识的,学号和课程号的组合唯一标识一条记录,因此学号+课程号的属性组是一个主键,成绩表中的学号与学生表中的学号是相对应的,且学号是学生表中主键,则称成绩表中的学号是学生表的
外键
主键只能有一个
- 外键
- 外键用于与另一张表的关联,能确定另一张表记录的字段,用于保持数据的一致性
- 外键可以重复,可以为空值
- 一个表可以有多个外键
- 索引
该字段没有重复值,但可以有空值
一个表可以有多个唯一索引
16.聚簇索引和非聚簇索引
- 聚簇索引:数据和索引都存放在一起,找到索引即可找到数据
一个表只有一个聚簇索引
- 非聚簇索引:将数据存储和索引分开,索引结构的叶子节点你指向数据的对应行
17.前缀索引
条件:有时候需要索引很长的字符(text或长varchar),这样会使得索引又大又慢
方法:
- 索引字符串的前几个字符,而不是全部值(前缀索引)
- 哈希索引
选择性:不重复的索引值 / 总记录数;范围是(0,1]
唯一索引的选择性等于1
前缀索引保持较高的选择性
18.MySQL/MongoDb 端口号
mysql:3306
mongodb:27017;
19.(多次)查询速度慢的原因,如何解决
- 没有创建索引
- IO吞吐量小
- 内存不足
- 网络环境
- 数据量过大
- 死锁或者锁问题
- 查询语句问题
20.redis中的数据结构及应用场景
redis有五种数据结构
- String
简单的key-value类型;常见的字符串操作
SET key value
存储键值对,set会覆盖旧值MSET key value [key value ...]
批量存储GET key
获取key对应的value值DEL key
删除key对应的键值对EXPIRE key seconds
设置key的有效时间
应用场景:
- 单值存储:
SET key value ; GET key
- 对象存储:
SET user:1 value
(json字符串)
存储:
MSET user:1: name zhangsan user:1:age 10
取:MGET user:1:name user:1:age
- 分布式锁
SETNX product :10001 true
返回1 表示加锁成功,返回0表示加锁失败
DEL product:10001
// 释放锁
SET product:10001 true ex 10 nx
// 防止程序意外终止导致死锁
-
计数器
统计阅读量:INCR article:readcount:{文章Id} 文章的阅读量统计
GET article:readcount:{文章Id}
-
分布式系统唯一id生成
INCRBY orderId 1000 redis
生成序列号,提升性能。`
- Hash
将一些结构化的信息打包成HashMap,在客户端序列化后存储为一个字符串的值
常用操作
HSET key field value
存储单个hash表的key的键值HSETNX key field value
存储一个不存在的hash表的key键值HMSET key field value [field value...... ]
存储多个键值对HGET key field
获取单个field的键值HGETALL key
返回hash表key中所有的键值对
应用场景
- 对象存储
HSET user:100001 name zhangsan age 10
//设置对象属性
HGET user:100001 name age
// 获取属性信息 - 电商购物车场景
- List
redis 中使用双链表实现list
应用场景
- 常用的数据结构
- Stack 栈 先进后出 FILO
- Queue 队列 FIFO 先进先出
- Blocking MQ 堵塞队列
- 微博和微信的公众号消息流
- Set
不重复值
应用场景
- 抽奖
- 微博微信点赞,关注,收藏等
- Sorted Set
增加了权重参数score,使得集合中的元素依照score有序排列
应用场景
- 微博热搜榜单
21.数据库隔离等级
脏读:session A读取了session B中未提交的数据
不可重复读:前后session A读取的数据不一致(读取了session B提交的数据)修改或删除
幻读:session A 读取到了session B插入的数据 插入
「1」设置隔离级别
全局的隔离级别:已存在的session不会生效,新session有效
set global transaction isolation level read uncommitted;
当前的隔离级别
*set session transaction isolation level read uncommitted;*
「2」查看当前隔离级别
select @tx_isolation;
22.为什么用B+树,不用hash索引
(1)二叉树
一个节点有两个子节点,左叉树小于该节点,右叉树大于该节点
升序
- 树的查询复杂度和树的高度有关,树越高,查询事件的复杂度就越高
- 某种约束来保证树的平衡性
(2)红黑树
平衡树:任何节点的两个子树的高度最大差为1
红黑树就是平衡二叉树的一种
- 根节点是黑色的
- 每个叶子节点都是黑色的空节点null
- 每个红色节点都有两个黑色的子节点
- 任意节点到红色节点的所有路径都包含相同的黑色节点
**缺点:**大数据存储,树的高度太高,可导致多次IO,查询效率低
(3)B树
B树是一个多路搜索树,每个节点可以有多个子节点,降低树的高度,减少磁盘IO次数
m阶B树:树中的每个节点至多m棵子树
- 非叶子节点的根节点至多有两棵子树
- 单个节点可以存储多个键值和数据
(4)B+树
- 子节点(索引节点)只存储键值,叶子节点(内部节点)存储数据
- 叶子节点间通过指针进行连接,有序形成链表(避免跨层)
- 子节点不存储数据,磁盘可以一次读取更多的子节点,减少IO次数
(5)hash索引
hash索引是将索引值经过Hash运算之后,将运算之后的hash值和所对应的行指针信息存放于一个Hash表中,不同的索引值可能存在相同的hash值 (hash冲突)
- hash索引查询单条数据比较快
- hash索引是无序的
- hssh索引只能满足”=”,”IN”和”<=>”查询