URML 2019-07-01
现在用的最多的数据模型是SQL,即关系模型,数据被组织成关系(SQL中称作表),其中每个关系是元组(SQL中称作行)无序集合。
NoSQL被重新解释为:Not Only SQL。
采用NoSQL数据库的背会有几个驱动因素,包括:
不同的应用程序有不同的需求,一个用例的最佳技术选择可能不同于另一个用例的最佳技术选择。
举例如果要保存一个人的简历,包括个人信息,学历,地址,网址,工作经历等等,如果用关系型数据库就需要很多张表来保存,用一个user_id来串起来。如果用NoSQL,就可以直接用一个json对象来保存起来。
Json表示比多表模式具有更好的局部性,如果在关系型示例中获取简历,那需要执行多个查询,或者在User表与其下属表之间混乱地执行多路连接。
一对多的好处是:
也会有好多对多的情况,好处跟一对多基本一致。
该处说的多对一和多对多都是基于关系数据库的。
最早的数据模型是一个层次模型,它与文档数据库使用的JSON模型有一些相似之处,它将所有数据表示为嵌套在记录中的记录数。
但是该模型能处理好一对多的关系,却很难处理多对多的情况,开发人员必须复制数据到另一个记录中。于是,人们提出了两种方案来解决层次模型的局限性:关系模型(就是现在的SQL),和网络模型(已经变的冷门)
网络模型是层次模型的推广,层次模型的树结构中,每条记录只有一个父节点,在网络模型中,每条记录可以能有多个父节点。
网络模型中,访问记录的唯一方法是跟随从根记录起沿这些链路所形成的路径,这被称为访问路径。
这种访问方式使得查询和更新数据库的代码变得复杂不灵活。无论是分层还是网络模型,如果你没有所需数据的路径,就会陷入困境。你可以改变访问路径,但是必须浏览大量手写数据库查询代码,并重写来处理新的访问路径。
这么难用,被淘汰是必然的。
关系模型中,一个关系(表)只是一个元组(行)的集合。可以通过指定某些列作为匹配关键字来读取特定行,你可以在任何表中插入一个新的行,而不必担心与其他表的外键关系。
关系模型的一个关键洞察是:只需构建一次查询优化器,随后使用该数据库的所有应用程序都可以从中受益。
一方面:文档数据库还原为层次模型:在其父记录中存储嵌套记录,而不是在单独的表中。
另一方面:在表示多对一和多对多的关系时,关系数据库和文档数据库并没有根本的不同:在这两种情况下,相关项目都被一个唯一的标识符引用,这个标识符在关系模型中被称为外键,在文档模型中被称为文档引用。
这两者进行比较时,可以考虑许多方面的差异,比如:容错属性,处理并发性等,本章只关注数据模型的差异。
文档数据模型:架构更灵活性,因局部性而拥有更好的性能,以及对于某些应用程序而言更接近应用程序使用的数据结构。
关系数据模型:为连接提供更好的支持,以及支持多对一和多对多的关系。
很难说在一般情况下那个数据模型让应用程序代码更简单,它取决于数据项之间存在的关系种类。
对于高度相联的数据,选用文档模型是糟糕的,选用关系模型是可以接受的。
如果程序大多是一对多关系或记录之间不存在关系,用文档类型更好。
如果有多对多关系,可以使用关系数据库,如果多对多的情况很复杂,可以使用图数据模型。
一个图由两个对象组成:顶点(也成为节点或实体),和边(也成为关系或弧),多种数据可以被建模为一个图形。
在属性图模型中,每个顶点(vertex)包括:
每条边(edge)包括:
Cypher是属性图的声明式查询语句,为Neo4j图形数据库而发明。
也可以在关系数据库中表示图数据,这样通过sql也能查询,但是这样存在很大的一些困难,在关系数据库中,你通常会事先知道在查询中需要哪些连接,而在图查询中,连接的数量事先并不确定,只有在找到待查询的顶点之前,遍历可变数量的边。
在三元组存储中,所有信息都以非常简单的三部分形式存储:主语,谓语,宾语。例如:三元组(吉姆,喜欢,香蕉)