[原理] 如果有人问你数据库的原理,叫他看这篇文章(笔记)

CRUD操作:Create(创建)、Retrieve(获取)、Update(更新)、Delete(删除)。

时间复杂度:在计算机科学中,时间复杂度是一个函数,它定量的描述了该算法的运行时间。

                                                        
 
本文要点:
1. 底层和上层组件概况
2. 查询优化过程概况
3. 事务和缓存池管理概况
 
时间复杂度:
 
当数据库以很快的速度从1条增加到10亿条,我们得出如下结论:
  • 绿,O(1) 或者叫常数阶复杂度,保持为常数
  • ,O(log(n))对数阶复杂度,即使在10亿数据量时也很低
  • ,O(n2)平方阶复杂度,最糟糕的复杂度,运算速快速膨胀
  • 黑和,这两种复杂度也是快速膨胀
举栗子:
    如果我们处理10000条数据,从O(1) →O(n2),运算次数大概是常数→100000000,后者1亿次看起来很大了,但是对于如今每秒亿级别的运算CPU来说也不会超过1秒
    如果我们处理的是1百万条数据,前者似乎也没多少,但后者会达到1000000000000,那你得需要喝杯茶的功夫了
    如果后面再加个零,那你就可以回家睡大觉了......
 
不同的数据结构对应不同的算法复杂度:
  • 搜索一个好的哈希表会得到O(1)复杂度
  • 搜索一个均衡的树会得到O(log(n))复杂度
  • 搜索一个阵列会得到O(n)复杂度
  • 最好的排序算法具有O(n*log(n))复杂度
  • 糟糕的排序算法具有O(n2)复杂度
  • 还有更糟糕的场景:具有 O(n4) —— 差劲、O(3n) —— 更差劲、O(阶层 n)——你永远得不到结果、O(nn) ——如果是这样,你该考虑考虑适不适合搞IT了
 
合并算法强大之处:
    合并算法为什么强大?因为:
        你可以更改算法,以便节省内存空间,方法是不创建新的序列而是直接修改输入列,这种算法叫做——原地算法(in-place algorithm)
        你可以更改算法,以便同时使用磁盘空间和少量的内存而避免巨量的磁盘I/O,方法是只向内存中加载当前处理的部分。在仅仅100M的内存区域排序几个G的表时,这是很重要的技巧,这种算法叫做——外部排序(external sorting).
        你可以更改算法,以便在多处理器/多线程/多服务器 上运行 ,这种算法叫做分布式合并排序,是Hadoop(著名大数据框架)的关键组件之一
 
这就是合并算法的强大之处,它可以点石成金!
 
三种数据库结构:(现代数据库的支柱)
 
1. 阵列  
2. 二叉树
3. 哈希表
 
二叉查找树
    ⑴ 比保存在左子树上的键值都要大
    ⑵ 比保存在右子树上的键值都要小
 
B+树索引:
    只有最底层的节点(叶子节点)才保存信息(相关表的行位置),其他节点只是在搜索中用来指引到正确的节点上。
 
 
查询管理器
 
一条Sql语句的人生经历:解析重写优化编译运行
解析:
    这一过程中,会检查你的SQL语句是否写正确,如 SELECT 不能写成 SELECC,还有 WHERE 必须在SELECT后面啦等
    以及语句中是否存在字符串与数字的比较,是否对数据使用substring()等
    还有,你所查询的表和字段是否存在,你是否有权限查询这些表字段等
    在解析的过程中,SQL查询会被转化为一个树结构(查询树
重写:
   这一步的目标: 预优化查询、避免不必要的运算、帮助优化器找到最佳的解决方案
    视图合并:如果Sql语句中使用了视图,那么会转换为它对应的Sql语句
    子查询扁平化:由于子查询很难优化,所以要转为连接查询
    去除不必要的运算符:如果你使用了 DISTINCT 还用了 UNIQUE 约束,那么 DISTINCT就被去掉了
    排除冗余连接:比如相同的 JOIN 出现两次等
    常数的计算赋值:如果你的查询需要计算,那么再重写的过程中会执行一次,比如 WHERE AGE>10+2 ,会转换为 WHERE AGE>12,TODATE()函数会转换为datetime格式的日期
    等等...
优化:
    统计信息:这是很好的数据,它可以帮助数据库找到更佳的执行计划,尤其对于等式谓词(=)、范围谓词(> and <),所以开启数据库的自动计算统计信息也是优化的一个步骤,当然是当数据量达到一定规模时间
 
 
基于成本的优化(CBO) Cost-Based Optimization:    与之对应的还有一个 基于规则的优化(RBR)Rule - Based Optimization:
    针对每个运算设置一个成本,通过比较一系列运算的成本找到最佳的查询方法
    注意:数据库大多数时候性能瓶颈出在磁盘I/O,而不是CPU的使用。
        索引:
            请记住一点,索引都是已经排过序的
针对一个SQL语句如何找到一个最佳的查询计划呢,数据库采用的是动态规划,会用到启发式算法、最近邻居算法、基因算法(PostgreSQL采用了基因算法)、贪婪算法、模拟退火算法、交互式改良算法、双阶段优化算法。
        查询计划缓存:由于创建查询计划是耗时的,一般数据库会把计划保存在查询计划缓存中。
 
事务管理器:
 
事务的四个属性:ACID 
    原子性(Atomicity):要么都完成,要么都取消
    一致性(Consistency):事务在开始之前和结束之后,数据库的完整性约束不被破坏
    隔离性(Isolation):如果俩个事务同时进行,那么俩个事务结束后结果是相同的。
    持久性(Durability):一旦事务提交,不管发生什么,数据都会保存在数据库中
 
SQL 的四个隔离级别
    串行化(Serializable SQLite 默认模式):发生的俩个事务百分之百隔离
    可重复读(Repeatable read MySql 默认模式):事务之间只在新数据方面突破隔离
    读取已提交(Read Committed Oracle、SqlServer、PostgreSQL默认模式)/不可重复读(non-repeatable read):新数据突破隔离+已有的被修改后并提交事务的数据突破隔离
    读取未提交(Read UnCommitted):最低级别,只要被修改或新增的数据,无论事务是否提交,都突破隔离,很少数据库实现
 
    快照隔离:部分数据库自定义实现
 
事务并发控制:
    1.使用锁机制
    2. 使用版本控制
DB2、SqlServer 仅使用锁机制,PostgreSQL、MySql、Oracle使用者两种混合机制
 
 
很不错的写关系数据库的文章,有兴趣的可以看全文,全文见:http://blog.jobbole.com/100349/
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2019-04-30 15:44  NCat  阅读(260)  评论(0)    收藏  举报