原文:https://blog.csdn.net/u012102104/article/details/79773362
Redis
介绍Redis
基于C语言开发的一种非关系型数据库,数据放在内存,使用RDB[快照]方式或者AOF[日志]方式持久化。
Redis的优势包括速度、对富数据类型的支持(String、Hash、List、Set、Zset)、原子性操作、通用性。
Redis使用场景
- 缓存(热数据:经常被查询,但不常被改变的数据)
- 共享Session(SSO系统)
- 队列 / 栈
- 位操作(大数据处理)
- 分布式锁(setnx命令)与单线程机制(秒杀系统)
- 排行榜 / 计数器(ZSet的zadd命令)
- 发布 / 订阅
MySQL
InnoDB引擎与MyISAM引擎
比较点 | InnoDB | MyISAM |
---|---|---|
事务 | 支持 | 不支持 |
外键 | 支持 | 不支持 |
锁 | 行锁 | 表锁 |
索引 | 聚集索引(数据和索引捆绑) | 非聚集索引(数据和索引分离) |
FullText索引 | 不支持 | 支持 |
跨平台 | 可直接拷贝 | 难直接拷贝 |
表格压缩 | 较难 | 较易 |
数据库事务
数据库事务是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。事务满足以下四大特性:
- 原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态。
- 一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
- 隔离性(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离级别 见Spring部分。
- 持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
数据库索引的实现
数据库索引包括B+树索引
、R树索引
、Hash索引
、FullText索引
等。
B树
一棵
m
m
m
mmm
mmm 阶 B 树,或为空树,或满足:
1. 每个结点至多有
m
m
m
mmm
mmm 棵子树。
2. 若根结点不是叶子,则至少有两棵子树。
3. 除根之外的所有非终端结点至少有
m
2
m
2
2
m
m2\frac{m}{2}2m
m22m2m 棵子树。
4. 所有非终端结点包含
n
n
n
nnn
nnn 个关键字和
n
+
1
n
+
1
n
+
1
n+1n+1n+1
n+1n+1n+1 棵子树,
n
n
n
nnn
nnn 满足:
m
2
−
1
≤
n
≤
m
−
1
m
2
−
1
≤
n
≤
m
−
12
m
−
1
≤
n
≤
m
−
1
m2−1≤n≤m−1\frac{m}{2} - 1 \leq n \leq m-12m−1≤n≤m−1
m2−1≤n≤m−12m−1≤n≤m−12m−1≤n≤m−1。
5. 所有叶子结点在同一层,不含信息,表示查找失败。
B+树
一棵
m
m
m
mmm
mmm 阶 B+ 树,或为空树,或满足:
1. 根结点只有一个,分支数量范围为
[
2
,
m
]
[
2
,
m
]
[
2
,
m
]
[2,m][2,m][2,m]
[2,m][2,m][2,m]。
2. 每个分支结点包含分支数范围为
[
m
2
,
m
]
[
m
2
,
m
]
[
2
m
,
m
]
[m2,m][\frac{m}{2},m][2m,m]
[m2,m][2m,m][2m,m]。
3. 分支结点的关键字数量等于其子分支的数量减一,关键字数量范围为
[
m
2
−
1
,
m
−
1
]
[
m
2
−
1
,
m
−
1
]
[
2
m
−
1
,
m
−
1
]
[m2−1,m−1][\frac{m}{2} - 1, m - 1][2m−1,m−1]
[m2−1,m−1][2m−1,m−1][2m−1,m−1],关键字顺序递增。
4. 所有叶子结点在同一层。
由于B+树的数据都存储在叶子结点中,分支结点均为索引,方便扫库,只需要扫一遍叶子结点即可,但是B树因为其分支结点同样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按序来扫。其中B树和B+树的区别如下:
- 关键字数量不同;B+树中 n 棵子树的结点中含有 n 个关键字;B树中 m 棵子树的结点中含有 m - 1 个关键字。
- 存储位置不同;B+树中所有叶子结点中包含了全部关键字,且按大小顺序排列;B树的数据存储在每一个结点中,并不仅仅存储在叶子结点上。
- 分支结点构造不同;B+树中所有非终端结点都是索引;B树中非终端结点存储数据。
- 查找方式不同;B+树中查找时走了一条从根结点到叶子结点的路径;B树中在找到具体的数值以后就结束,并不一定到叶子结点。
B树:有序数组+平衡多叉树;
B+树:有序数组链表+平衡多叉树;
B+树的关键字全部存放在叶子节点中,非叶子节点用来做索引,而叶子节点中有一个指针指向一下个叶子节点。做这个优化的目的是为了提高区间访问的性能。而正是这个特性决定了B+树更适合用来存储外部数据。
R树(空间索引)
一棵R树满足如下的性质:
- 除根结点之外,所有非根结点包含有 m 至 M 个记录索引,根结点的记录个数可以少于 m 。通常 M = 2m 。
- 对于所有叶子结点中存储的记录,I 是最小的可以在空间中完全覆盖这些记录所代表的点的矩形(此处“矩形”可以扩展到高维空间)。
- 对于所有非叶子结点上的记录,i 是最小的可以在空间上完全覆盖这些条目所代表的点的矩形。
- 所有叶子结点在同一层。
R树是B树在K维上的自然扩展
InnoDB引擎的索引实现结构
MyISAM引擎的索引实现结构
左右连接
- 左连接(left join):显示左表所有数据和右表相应数据。
- 右连接(right join):显示右表所有数据加左表相应数据。
- 内连接(inner join):显示有效公共数据。
- 全连接(full join):显示所有数据。
左连接只影响右表,右连接只影响左表
范式
第一范式(1NF)
所谓第一范式(1NF)是指在关系模型中,对域添加的一个规范要求,所有的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。即实体中的某个属性有多个值时,必须拆分为不同的属性。在符合第一范式(1NF)表中的每个域值只能是实体的一个属性或一个属性的一部分。
> 简而言之,第一范式就是无重复的域。
第二范式(2NF)
在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)。第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或记录必须可以被唯一地区分,选取一个能区分每个实体的属性或属性组,作为实体的唯一标识。
> 简而言之,第二范式就是在满足第一范式的基础上,属性完全依赖于主键。
第三范式(3NF)
在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)。第三范式(3NF)是第二范式(2NF)的一个子集,即满足第三范式(3NF)必须满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个关系中不包含已在其它关系已包含的非主关键字信息。
> 简而言之,第三范式就是在满足第二范式的基础上,属性不依赖于其它非主属性。
分库后如何实现分页查询
- 直接使用跨库的多表联合查询(不建议)。
- 向每个数据库均发送一个查询请求,然后对所有查询结果汇总,再处理分页逻辑。
- 建立一个总数据库,只负责维护主键和必要的索引,以供分页查询。
- 使用Redis维护一个主键序列,分页操作就是截取该序列的一部分,其结果就是主键ID集合,拿到ID后便可映射到多个数据库查询数据。
“多台”数据库访问的问题无解,但同台“多次”数据库访问的问题可以通过程序优化。
SQL注入的原理,如何预防
所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
- 对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号和双"-"进行转换等。
- 不要使用动态拼装SQL,应使用参数化的SQL或者直接使用存储过程进行数据查询存取。
- 不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
- 不要把机密信息明文存放,应加密或者Hash掉密码和敏感的信息。
- 使用自定义的错误信息对原始错误信息进行包装,把异常信息存放在独立的表中。