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

关系型数据库隔离了数据的存储路径,让用户只关心查询的逻辑,为了实现事物和强一致性通过各种锁牺牲了性能
互联网在线处理需求排列
数据的扩展性 > 请求的响应时间 > 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. 移植RTL8188CUS USB-WIFI(移植失败)

    1.主makefile CONFIG_POWER_SAVING = n CONFIG_PLATFORM_I386_PC = n CONFIG_PLATFORM_HI3518E = y ##swann ...

  2. mac上安装nginx

    终端执行: brew install nginx nginx 默认安装在 /usr/local/Cellar/nginx/1.12.2 conf 文件默认安装在 /usr/local/etc/ngin ...

  3. Generator 知识点

    Generator 函数的执行过程,其实是将同一个回调函数,反复传入 next 方法的 value 属性. Iterator 接口的 next 方法必须是同步的,只要调用就必须立刻返回值.也就是说,一 ...

  4. SQL Server Reporting Service 报错:报表服务器无法解密用于访问报表服务器数据库中的敏感数据或加密数据的对称密钥,必须还原备份密钥或删除所有加密的内容。

    出现这个问题,可以通过reporting services 配置管理工具来处理 首先,打开配置管理工具,连接. 在左侧的导航选项中选择Encryption Keys,将出现如图所示的界面,在右侧点击d ...

  5. 用pyenv 和 virtualenv 搭建单机多版本python 虚拟开发环境

    作为主流开发语言, 用python 开发的程序越来越多. 方便的是大多linux系统里面都默认集成了python, 开发可以随时随地开始. 但有时候这也成为了一个短板, 比如说有时候我们需要开发和调试 ...

  6. 利用spring的ApplicationListener实现springmvc容器的初始化加载--转

    1.我们在使用springmvc进行配置的时候一般初始化都是在web.xml里面进行的,但是自己在使用的时候经常会测试一些数据,这样就只有加载spring-mvc.xml的配置文件来实现.为了更方便的 ...

  7. css调用方式的方法

    1.内部样式表(位于 <head> 标签内部) <html><style>.box{display:inline}p { color: rgb(255,0,0); ...

  8. 学习笔记之XML

    什么是QName - Benjieming_Wang的专栏 - CSDN博客 http://blog.csdn.net/Benjieming_Wang/article/details/5959961 ...

  9. JavaScript方法和技巧大全

    原文地址:http://www.jb51.net/article/5688.htm 这篇介绍JavaScript方面的日志,我在是Clang上看到的.作者介绍挺全面的,所以转载过来让感兴趣的朋友看一下 ...

  10. [UE4]添加蒙太奇动画

    选择蒙太奇所使用的骨骼