NOSQL这个概念其实唱了好多好多年了,但是真正浸淫其中, 理解深刻并享受到红利的人占比其实并不高。 近期笔者自己会在大数据、图数据等方面边学习边记录一些笔记,持续分享自己的心得体会,此文权当发力之前的开山篇,希望更多关心该领域的朋友多多关注、支持和帮助。
NOSQL的概念
刚刚出现NOSQL这个概念的时候,很多人都是似而非的字面理解成"不是SQL", 与传统的关系型数据库是两个完全独立的阵营,实际上完全不是这么回事。个人更倾向于理解NOSQL的诞生更多的是为了补充关系型数据库的短板,满足现下互联网海量数据、高并发、低延迟和非结构化数据易扩展等需求。
NoSQL = Not Only SQL,意即“不仅仅是SQL”,是对不同于传统的关系型数据库的数据库管理系统的统称。与关系型数据库相比,它们在架构和数据模型方面做了“减法”,而在扩展和并发等方面做了“加法”。
NOSQL简史
NoSQL一词最早出现于1998年,是Carlo Strozzi开发的一个轻量、开源、不提供SQL功能的关系数据库。
2009年,Last.fm的Johan Oskarsson发起了一次关于分布式开源数据库的讨论,来自Rackspace的Eric Evans再次提出了NoSQL的概念,这时的NoSQL主要指非关系型、分布式、不提供ACID的数据库设计模式。
2009年在亚特兰大举行的"no:sql(east)"讨论会是一个里程碑,其口号是"select fun, profit from real_world where relational=false;"。因此,对NoSQL最普遍的解释是"非关联型的",强调Key-Value Stores和文档数据库的优点,而不是单纯的反对RDBMS。
为何要使用NoSQL
NoSQL具有灵活的数据模型,可以处理非结构化/半结构化的大数据
NoSQL很容易实现可伸缩性(向上扩展与水平扩展)
NoSQL在不太影响性能的情况,就可以方便的实现高可用的架构
NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。
NOSQL的分类
主流的NoSQL数据库主要分为4类:
键值(Key-Value)存储数据库
这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署。但是如果DBA只对部分值进行查询或更新的时候,Key/value就显得效率低下了。例如:Redis,Memcache, DynamoDB等
列存储(Wide-Column)数据库
这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase。
文档型(Document)数据库
文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可 以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。如:CouchDB, MongoDB。
图形(Graph)数据库
图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。 如:OrientDB, Neo4J, Titan等。
其他还有类似对象数据库,XML数据库大家自行搜索吧。另外很多NOSQL数据库其实是支持多模型的,比如OrientDB同时支持Key-Value, Document, Graph, Object数据库。
更多NOSQL数据库列表请看
http://nosql-database.org/
十万个为什么
列数据库到底牛逼在哪里
其实应该这么说,列数据库只有在OLAP,或者说对部分列进行聚合操作的场景下, 比如sum、count、groupby之类的运算,它确实优秀。但是如果是OLTP,大量的更新或者大量的整行查询,那列数据库没有优势,甚至反而会比RDBMS更慢。
列数据库的存储方式与行数据库也有显著不同:行式存储中,主键是rowid,由它关联到索引数据;列式存储中,主键是数据本身,关联回rowid,即“数据即索引”。
这里有个对比的paper, 有兴趣的可以读一下
http://db.csail.mit.edu/projects/cstore/abadi-sigmod08.pdf
列存储 vs 行存储 WIKI
https://en.wikipedia.org/wiki/Column-oriented_DBMS
文档DB VS键值DB
它俩的主要区别简单一句话,就是:键值DB不知道Value的格式和内容,而文档DB知道且可以在格式化的Value内容(Json/XML)上建立索引进行查询。
我是不是说的挺明白的?
图DB做社交关系为什么快
我们就以社交网络为例,来简要说明下图数据库到底快在哪里。 如下我们有个朋友关系表:
> SELECT * FROM friends;
------------- --------------
| user_id | friend_id |
------------- --------------
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 2 | 5 |
| 2 | 6 |
| 2 | 7 |
| 3 | 8 |
| 3 | 9 |
| 3 | 10 |
------------- --------------
对于关系型数据库来说,这种多对多的模型,除了基本的users表之外, 这个朋友之间的映射关系表必然需要建一张。
也就是说虽然我们RDBMS这么多年的数据库设计,比如ER设计中的Relationship或者以外键的形式存在,或者以中间表的形式存在。
我们现在需要查询这样一个场景,找userid=1用户的朋友的朋友,也就是社交网络里的2度查询,大家想想这个SQL应该怎么写(不难,大家自己试验一下吧)。
问题是在互联网海量数据的社交模型中,2度查询太简单了,6度查询或者更高呢?你这个SQL语句还能写出来么或者说能跑出来么?(6度查询的笛卡尔积是相当恐怖的数字)。
但是对于图数据库而言,Relationship关系是一等公民(在图数据库领域一般叫做Edge, 图中的箭头), 与上图中用户本身的顶点Vetex(图中的圆)是相同的地位。
在图数据库中,我要查询userid=1用户的朋友的朋友,只需要先定位到Vertex(1),然后从这个顶点遍历所有的friend Edge, 就可以查询出想要的结果,就算是6度查询,也不过是多了几层遍历而已,这个性能的消耗是线性的,完全不是关系型数据库笛卡尔积的指数性增长可比!
100个用户可能区别不大,但如果是100w的用户关系图谱,对于图数据库而言都是从一个点来遍历,性能没有明显的区别。
有个比较好理解的类比,想象你作为一个观众坐在八万人体育馆看球赛,这是一场没人关注的比赛,赛场只做了100个人,那在你座位旁边的人(视作有关系)是有限的几个人,或者甚至旁边没人;但是如果这是一场同城德比超级火爆的比赛,赛场坐满了八万人,坐在你旁边跟你有关系的人其实还是有限的那几个而已(有限“度”的遍历),离你远的人对从你开始的遍历没有任何显著的影响!
这就是图数据库的魅力, 我应该说明白了吧?
再来几个装逼理论
六度分离问题
六度分离(六度区隔)理论(Six Degrees of Separation):“你和任何一个陌生人之间所间隔的人不会超过五个,也就是说,最多通过五个人你就能够认识任何一个陌生人。”
根据这个理论,你和世界上的任何一个人之间只隔着五个人,不管对方在哪个国家,属哪类人种,是哪种肤色。
这个理论也是做社交网络的一个基本理念。
柯尼斯堡七桥问题
-- 一笔画问题
在哥尼斯堡的一个公园里,有七座桥将普雷格尔河中两个岛及岛与河岸连接起来(如图)。问是否可能从这四块陆地中任一块出发,恰好通过每座桥一次,再回到起点?欧拉于1736年研究并解决了此问题,他把问题归结为如右图的“一笔画”问题,证明上述走法是不可能的。
这个问题的解决被世人作为图论的起源来看待,欧拉也由此被称为“图论之父”。