单机SQL Join的原理分析

Join在SQL是给两个或以上表建立连接的基本操作,本文以TenDB (开源MySQL分支) 为例,介绍Join算法的底层原理。 更多TenDB Cluster相关技术交流,欢迎加入 QQ群: 584695931   官方网址: https://tendbcluster.com TSpider: https://github.com/Tencent/TenDBCluster-TSpider TenDB: https://github.com/Tencent/TenDBCluster-TenDB Tdbctl: https://github.com/Tencent/TenDBCluster-Tdbctl   单机Join — 以TenDB为例 以下面的表结构和数据为例: CREATE TABLE t2 ( id INT PRIMARY KEY AUTO_INCREMENT, a INT, b INT, # b是一个普通列 KEY ka(a) # a上有个索引, id是主键 )ENGINE=INNODB; # 插入数据 (1,1,1)到(1k,1k,1k)共1000条 INSERT INTO t2 VALUES(1,1,1),(2,2,2),…,(1000,1000,1000); # t1与t2表结构相同,是t2的前100条数据 CREATE TABLE t1 LIKE t2;INSERT INTO t1 (SELECT * FROM t2 WHERE id<=100);   Nested Loop Join 对于基于索引a的两表Join语句: SELECT * FROM… Continue reading 单机SQL Join的原理分析

Published
Categorized as 数据库

3w字深度好文|Redis面试全攻略,读完这个就可以和面试官大战几个回合了

当前浏览器不支持播放音乐或语音,请在微信或其他浏览器中播放 那女孩对我说 黄义达 – 歌曲合辑 0x00.前言 众所周知数据结构和算法是面试重点,我们持续发力是十分明智的,要不然最后肯定是要吃亏的,少打打游戏刷刷微博可以改变我们的生活水平哦。 不过本文不是要讲述数据结构和算法的,而是另外一个面试重点Redis,因为Redis也是跨语言的共同技术点,无论是Java还是C++都会问到,所以是个高频面试点。 笔者是2017年才开始接触Redis的,期间自己搭过单机版和集群版,不过现在公司大一些都完全是运维来实现的,我们使用者只需要在web页面进行相关申请即可,很多细节都被屏蔽了,这样当然很方便啦,不过我们还是要深入理解一下的。 在工作几年中笔者接触过Redis、类Redis的SSDB和Pika、谷歌的Key-Value存储引擎LevelDB、FackBook的Key-Value存储引擎RocksDB等NoSQL,其中Redis是基于标准C语言开发的,是工程中和学习上都非常优秀的开源项目。 之前笔者写过几篇左右Redis的文章,但是知识点都分散着不利于阅读,所以本次就把之前的文章进行汇总补充,来形成一个全一些的集合,希望对关注我的读者有所帮助就足够啦。 文中列出来的考点较多并且累计达3w+字 ,因此建议读者收藏,以备不时之需,通过本文你将了解到以下内容: Redis的作者和发展简史 Redis常用数据结构及其实现 Redis的SDS和C中字符串的原理和对比 Redis有序集合ZSet的底层设计和实现 Redis有序集合ZSet和跳跃链表问题 Redis字典的实现及渐进式Rehash过程 Redis单线程运行模式的基本原理和流程 Redis反应堆模式的原理和设计实现 Redis持久化方案及其基本原理 集群版Redis和Gossip协议 Redis内存回收机制和基本原理 Redis数据同步机制和基本原理 话不多说,时速400公里的大白号 开始加速! 笔者尽量详细地阐述每个问题,旨在深入理解避免囫囵吞枣的背诵,当然也会存在一些不足,如有问题可私信我。 0x01. 什么是Redis及其重要性? Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久化的高性能键值对数据库。 Redis的之父是来自意大利的西西里岛的Salvatore Sanfilippo,Github网名antirez,笔者找了作者的一些简要信息并翻译了一下,如图: 从2009年第一个版本起Redis已经走过了10个年头,目前Redis仍然是最流行的key-value型内存数据库的之一。 优秀的开源项目离不开大公司的支持,在2013年5月之前,其开发由VMware赞助,而2013年5月至2015年6月期间,其开发由毕威拓赞助,从2015年6月开始,Redis的开发由Redis Labs赞助。 笔者也使用过一些其他的NoSQL,有的支持的value类型非常单一,因此很多操作都必须在客户端实现,比如value是一个结构化的数据,需要修改其中某个字段就需要整体读出来修改再整体写入,显得很笨重,但是Redis的value支持多种类型,实现了很多操作在服务端就可以完成了,这个对客户端而言非常方便。 当然Redis由于是内存型的数据库,数据量存储量有限而且分布式集群成本也会非常高,因此有很多公司开发了基于SSD的类Redis系统,比如360开发的SSDB、Pika等数据库,但是笔者认为从0到1的难度是大于从1到2的难度的,毋庸置疑Redis是NoSQL中浓墨重彩的一笔,值得我们去深入研究和使用。   Redis提供了Java、C/C++、C#、 PHP 、JavaScript、 Perl 、Object-C、Python、Ruby、Erlang、Golang等多种主流语言的客户端,因此无论使用者是什么语言栈总会找到属于自己的那款客户端,受众非常广。 笔者查了datanyze.com网站看了下Redis和MySQL的最新市场份额和排名对比以及全球Top站点的部署量对比(网站数据2019.12): 可以看到Redis总体份额排名第9并且在全球Top100站点中部署数量与MySQL基本持平,所以Redis还是有一定的江湖地位的。 0x02. 简述Redis常用的数据结构及其如何实现的? Redis支持的常用5种数据类型指的是value类型,分别为:字符串String、列表List、哈希Hash、集合Set、有序集合Zset,但是Redis后续又丰富了几种数据类型分别是Bitmaps、HyperLogLogs、GEO。 由于Redis是基于标准C写的,只有最基础的数据类型,因此Redis为了满足对外使用的5种数据类型,开发了属于自己独有的一套基础数据结构,使用这些数据结构来实现5种数据类型。 Redis底层的数据结构包括:简单动态数组SDS、链表、字典、跳跃链表、整数集合、压缩列表、对象。 Redis为了平衡空间和时间效率,针对value的具体类型在底层会采用不同的数据结构来实现,其中哈希表和压缩列表是复用比较多的数据结构,如下图展示了对外数据类型和底层数据结构之间的映射关系: 从图中可以看到ziplist压缩列表可以作为Zset、Hash、List三种数据类型的底层实现,看来很强大,压缩列表是一种为了节约内存而开发的且经过特殊编码之后的连续内存块顺序型数据结构,底层结构还是比较复杂的。 0x03. Redis的SDS和C中字符串相比有什么优势? 在C语言中使用N+1长度的字符数组来表示字符串,尾部使用’\0’作为结尾标志,对于此种实现无法满足Redis对于安全性、效率、丰富的功能的要求,因此Redis单独封装了SDS简单动态字符串结构。… Continue reading 3w字深度好文|Redis面试全攻略,读完这个就可以和面试官大战几个回合了

Published
Categorized as 数据库

图解|高性能服务器设计之缓存系统一致性

缓存系统交互 缓存系统设计是后端开发人员的必备技能,也是实现高并发的重要武器。 对于读多写少的场景,我们通常使用内存型数据库作为缓存,关系型数据库作为主存储,从而形成两层相互依赖的存储体系。 < data-tool=”mdnice编辑器” style=”border-top: none; border-bottom: none; font-size: 0.9em; overflow: auto; color: #6a737d; padding: 10px 10px 10px 20px; margin-bottom: 20px; margin-top: 20px; border-left-color: rgba(0, 0, 0, 0.65); border-right: 1px solid rgba(0, 0, 0, 0.65); background: #f9f9f9;”> 共识:我们将使用Redis和MySQL作为缓存和主存的实体,展开今天的话题。 </> 缓存系统需要处理读取场景和更新场景: 读取时只要之前MySQL和Redis中的数据是一致的,后续只要没有更新操作就不会有什么问题,借助于内存读取速度来提高并发能力,这也是我们设计缓存系统的初衷。 单纯读取的情况并不多,即使是读多写少的业务模型,也还是会有更新操作,由于操作MySQL和Redis并非天然的原子操作,因此需要我们特殊处理。 读取过程示意: < data-tool=”mdnice编辑器” style=”border-top: none; border-bottom: none; font-size: 0.9em; overflow: auto; color:… Continue reading 图解|高性能服务器设计之缓存系统一致性