异步,最终一致性,幂等操作

关系型数据库隔离了数据的存储路径,让用户只关心查询的逻辑,为了实现事物和强一致性通过各种锁牺牲了性能
互联网在线处理需求排列
数据的扩展性 > 请求的响应时间 > down机时间 > 成本 > 快速自动恢复 > 数据的读取一致性 > 开发相关
 
多机事物  多机join 分布式索引
 
预写日志WAL,队列记录了每次的写操作(用户的一次写操作可能对应计算机内的多步操作),利用操作系统的院子操作fsync()将一小段数据写入磁盘,保证数据不丢失
 
触发器都是同步的,只有写入数据操作和触发器操作都执行完了才算结束
 
关系表叫T,有三个行组成 pk,cash,col2
映射的key是pk的值,value则是cash+col2的组合:
那么,select * from T where pk= 100020这个查询就可以被转译成一个非常简单的针对映射的操作了,map.get(100020)
sql解析器 => 执行优化器 => 锁  => 映射[读取主数据] =>触发器[触发读取事件] =>锁[释放读锁]
 
select * from T where cash= 100
建立一个新的映射关系idx_cash,针对原有T表中部分数据的重排,key是cash,value则是pk。主索引或一级索引是PK为key的数据,非PK为key的数据成为二级索引或辅助索引。当执行查询时,先查辅助索引idx_cash,以logN的复杂度找到一批pk数据,然后再去住索引中按照pk去找到记录。

sql解析器 => 执行优化器 => 锁[申请读锁(或使用MVCC)] => 映射[读取二级索引] => 映射[读取主数据] =>触发器[触发读取事件] =>锁[释放读锁]

 
insert into T (pk,cash,col2) values (100,10,20)
sql解析器 => 执行优化器 => 锁[申请写锁,同时锁住主数据和辅助索引数据] => 映射[读取主索引,判断该值是否存在] =>预写式日志[写入数据日志]=> 映射[写入数据,如果不存在] =>触发器[触发写入事件] => 映射[根据触发器,更新二级索引] => 触发器[触发二级索引写入事件] =>预写式日志[标记该条记录全部写入完成]=>锁[释放写锁]
 

begin transaction ;

预写式日志[声明一个事务的唯一标记]

select cash from T where pk = 1;

sql解析器 => 执行优化器 => 锁[申请读锁] => 映射[读取主数据] =>触发器[触发读取事件]

update T set cash = cach-100 where pk = 1;

sql解析器 => 执行优化器 => 锁[读锁升级为写锁] => 映射[读取主数据pk=1]  => 预写式日志[写入数据日志,添加事务的唯一标记] => 映射[写入数据] =>触发器[触发写入事件] => 映射[根据触发器,更新二级索引] => 触发器[触发二级索引写入事件]

update T set cach = cash+100 where pk =2;

sql解析器 => 执行优化器 => 锁[读锁升级为写锁] => 映射[读取主数据pk=2]  => 预写式日志[写入数据日志,添加事务的唯一标记] => 映射[写入数据] =>触发器[触发写入事件] => 映射[根据触发器,更新二级索引] => 触发器[触发二级索引写入事件]

commit;

预写式日志[标明该事务提交]

DB磁盘读写优化:一次性读取或写入固定大小的一块数据,并尽可能的减少随机寻道这个操作的次数
 
B树原位写入:查找到当前数据对应块的位置(找到某个块【数据块包含了一组个数有限的有序数据】,检查主键约束,是否需要分裂),然后将新数据写入到刚才找到的数据块,然后再查找到块所对应的磁盘物理位置,将数据写入。假定内存只能容纳一个B树块大小的数据,操作需要两次随机寻道(一次查找,一次原位写)
EG:   现有块 0,1,2|3,4,5|6,7,9 , 写入8 
先找到块6,7,9 ==> 放不下,分裂为两个块 ==> 写出后变为 0,1,2|3,4,5|6,7,空|8,9,空
 
内存满了之后如何将数据写回磁盘
1. 原位写入(Innodb),不浪费空间,保证查询O(log2n)
2. 队尾写入,不做原位替换,只将新写入的数据追加到整个数据的尾部,加快写入速度,缺点是老值还在原数据块中,占用了额外的空间。树1:0,1,2|3,4,5|6,7,9; 树2:5',8,9'
读取最新值: 
A. 每次将内存中的树和硬盘中的树做合并后写到新位置,并更新父节点的指针--磁盘增删次数多了导致磁盘空洞,随机跳跃存在,对范围查询不友好,读取的随机IO增加
B. 内存中存在一个或者多个有序树结构,读取根据时间顺序倒着去多个树种一次查找,结果第一个找到的就是最新值。
 
空间浪费:
后台开一个线程,利用异步归并排序的方式将多个小的有序树进行合并后追加。因为是异步并且写出来的数据也是有序的,所以也尽可能降低磁盘寻到次数
树1:0,1,2|3,4,5|6,7,9; 树2:5',8,9' ;  树3:0,1,2|3,4,5'|6,7,8|9',此时树3已经包含了树1.2,删除他俩即可。
 
LSM Tree(log structured merge tree),针对传统b树在磁盘写入性能上的优化。放弃部分读能力换取写入能力的最大化。假定内存足够大,不需要每次更新都写入磁盘,可以先将最新的数据驻留在磁盘中,等积累到一定程度,再用归并方式将内存数据合并追加到磁盘队尾
SSTable/Merge-dump模型的LSMTree: 避免写入太多,内存不够,所以定期将内存数据刷写到磁盘尾部并清空内存,通过良好的缓存和compaction机制以及适当的bloom-filter可以降低对读效率的影响
 

学习笔记-db的更多相关文章

  1. rails学习笔记: rake db 相关命令

    rails学习笔记: rake db 命令行 rake db:*****script/generate model task name:string priority:integer script/g ...

  2. Linux 学习笔记

    Linux学习笔记 请切换web视图查看,表格比较大,方法:视图>>web板式视图 博客园不能粘贴图片吗 http://wenku.baidu.com/view/bda1c3067fd53 ...

  3. MongoDB学习笔记—权限管理

    1.MongoDB权限介绍 a 上篇文章中,我们在Linux下配置了MongoDB环境并且将其设置为服务随机器启动而启动,那么接下来这篇文章我们就来简单说一下MongoDB下对登录用户权限的管理. b ...

  4. MongoDB学习笔记~环境搭建

    回到目录 Redis学习笔记已经告一段落,Redis仓储也已经实现了,对于key/value结构的redis我更愿意使用它来实现数据集的缓存机制,而对于结构灵活,查询效率高的时候使用redis就有点不 ...

  5. Redis学习笔记4-Redis配置详解

    在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redi ...

  6. linq学习笔记

    最近在学习linq的一些基础知识,看了c#高级编程及阅读了园子内部几篇优秀的博文,有所体会,感觉应该记录下来,作为以后复习使用.都是一些最基础的知识,大致分为三个部分:linq预备知识:linq查询: ...

  7. [原创]java WEB学习笔记109:Spring学习---spring中事物管理

    博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好 ...

  8. [原创]java WEB学习笔记109:Spring学习---spring对JDBC的支持:使用 JdbcTemplate 查询数据库,简化 JDBC 模板查询,在 JDBC 模板中使用具名参数两种实现

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  9. X-Cart 学习笔记(二)X-Cart框架1

    目录 X-Cart 学习笔记(一)了解和安装X-Cart X-Cart 学习笔记(二)X-Cart框架1 X-Cart 学习笔记(三)X-Cart框架2 X-Cart 学习笔记(四)常见操作 四.X- ...

随机推荐

  1. linux修改文件所有者和文件所在组

      chgrp  用户名    文件名  -R chown 用户名   文件名  -R -R表示递归目录下所有文件 以上部分已验证 一.修改文件所属组群——chgrp    修改文件所属组群很简单-c ...

  2. 投行的码工 Dead-end job

    发信人: icestonesy (无忧), 信区: Quant 标  题: 投行的码工怎么样? 发信站: BBS 未名空间站 (Sat May 16 23:25:00 2015, 美东) 最近看到不少 ...

  3. v-if 与 v-show 区别

    使用 v-if 时,如果在初始化渲染的时候条件为false, 那么不会做任何事情. v-if 首次局部编译不会发生,直到条件变为true. v-if 切换显示内容的消耗更高,而 v-show 在初始化 ...

  4. 设置zedgraph鼠标拖拽和局部放大属性(转帖)

    说一下几个属性的意义和具体应用: (1)鼠标拖拽显示区域 PanModifierKeys ->> Gets or sets a value that determines which mo ...

  5. C#之设计模式之六大原则

    一.单一职责原则 原文链接:http://blog.csdn.net/lovelion/article/details/7536542 单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小. ...

  6. js正则表达式30分钟入门教程

    2011-10-27 13:23:15 如何使用本教程 最重要的是——请给我30分钟,如果你没有使用正则表达式的经验,请不要试图在30秒内入门——除非你是超人 :) 别被下面那些复杂的表达式吓倒,只要 ...

  7. Eclipse设置相同变量背景色高亮显示

    在Eclipse中,鼠标选中或者光标移动到java类的变量名时,相同变量会被标识显示(设置背景色高亮), 并且侧边滚动条会标出变量的位置, 查找变量十分方便. 1.相同变量标识高亮显示: Window ...

  8. 实际用户ID和有效用户ID (一) *****

    在Unix进程中涉及多个用户ID和用户组ID,包括如下: 1.实际用户ID和实际用户组ID:标识我是谁.也就是登录用户的uid和gid,比如我的Linux以simon登录,在Linux运行的所有的命令 ...

  9. 第5章 pandas入门

    pandas是专门为处理表格和混杂数据设计的,NumPy更适合处理统一的数值数组数据. pandas的数据结构: Series:Series是一种类似于一维数组的对象,它由一组数据(各种NumPy数据 ...

  10. R语言学习——输入与输出

    导入数据: grades<-read.table("D:/ProgramData/test1.txt",sep="\t") 求均值:mean() 求方差: ...