NoSQL,泛指非关系型的数据库,全称Not Only SQL,意即“不仅仅是SQL”。
NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。在过去几年,关系型数据库一直是数据持久化的唯 一选择,数据工作者考虑的也只是在这些传统数据库中做筛选,比如SQL Server、Oracle或者是MySQL。甚至是做一些默认的选择,比如使用.NET的一般会选择SQL Server;使用Java的可能会偏向Oracle,Ruby是MySQL,Python则是PostgreSQL或MySQL等等。
原因很简单:过去很长一段时间内,关系数据库的健壮性已经在多数应用程序中得到证实。我们可以使用这些传统数据库良好的控制并发操作、事务等等。然 而如果传统的关系型数据库一直这么可靠,那么还有NoSQL什么事?NoSQL之所以生存并得到发展,是因为它做到了传统关系型数据库做不到的事!
我们使用Python、Ruby、Java、.Net等语言编写应用程序,这些语言有一个共同的特性——面向对象。但是我们使用MySQL、 PostgreSQL、Oracle以及SQL Server,这些数据库同样有一个共同的特性——关系型数据库。这里就牵扯到了“Impedance Mismatch”( 阻抗不匹配)这个术语:存储结构是面向对象的,但是数据库却是关系的,所以在每次存储或者查询数据时,我们都需要做转换。Hibernate这样的ORM 框架确实可以简化这个过程,但是在对查询有高性能需求时,这些ORM框架就捉襟见肘了。
网络应用程序的规模日渐变大,我们需要储存更多的数据、服务更多的用户以及需求更多的计算能力。为了应对这种情形,我们需要不停的扩展。扩展分为两 类:一种是纵向扩展,即购买更好的机器,更多的磁盘、更多的内存等等;另一种是横向扩展,即购买更多的机器组成集群。在巨大的规模下,纵向扩展发挥的作用 并不是很大。首先单机器性能提升需要巨额的开销并且有着性能的上限,在Google和Facebook这种规模下,永远不可能使用一台机器支撑所有的负 载。鉴于这种情况,我们需要新的数据库,因为关系数据库并不能很好的运行在集群上。不错你也可能会去搭建关系数据库集群,但是他们使用的是共享存储,这并 不是我们想要的类型。于是就有了以Google、Facebook、Amazon这些试图处理更多传输所引领的NoSQL纪元。
NoSQL数据库在以下的这几种情况下比较适用:
1、数据模型比较简单;
2、需要灵活性更强的IT系统;
3、对数据库性能要求较高;
4、不需要高度的数据一致性;
5、对于给定key,比较容易映射复杂值的环境。
NoSQL数据库的四大家族
一、键值(Key-Value)数据库
键值数据库就像在传统语言中使用的哈希表。你可以通过key来添加、查询或者删除数据,鉴于使用主键访问,所以会获得不错的性能及扩展性。
键值数据库查找速度快,数据无结构化,通常只被当作字符串或者二进制数据。
适用的场景
储存用户信息,比如会话、配置文件、参数、购物车等等。这些信息一般都和ID(键)挂钩,这种情景下键值数据库是个很好的选择。
不适用场景
1. 取代通过键查询,而是通过值来查询。Key-Value数据库中根本没有通过值查询的途径。
2. 需要储存数据之间的关系。在Key-Value数据库中不能通过两个或以上的键来关联数据。
3. 事务的支持。在Key-Value数据库中故障产生时不可以进行回滚。
产品:Riak、Redis、Memcached、Amazon’s Dynamo、Project Voldemort
- Riak
Riak是以 Erlang 编写的一个高度可扩展的分布式数据存储,Riak的实现是基于Amazon的分布式key/value存储引擎Dynamo,如图1所示。
图1
Riak的设计目标之一就是高可用。Riak支持多节点构建的系统,每次读写请求不需要集群内所有节点参与也能胜任。提供一个灵活的 map/reduce 引擎,一个友好的 HTTP/JSON 查询接口。目前有三种方式可以访问 Riak:HTTP API(RESTful 界面)、Protocol Buffers 和一个原生 Erlang 界面。提供多个界面使你能够选择如何集成应用程序。
riak-java-client 是 Riak 的 Java 客户端开发类库,示例代码:
// create a client
IRiakClient riakClient = RiakFactory.pbcClient(); //or RiakFactory.httpClient();
// create a new bucket
Bucket myBucket = riakClient.createBucket("myBucket").execute();
// add data to the bucket
myBucket.store("key1", "value1").execute();
//fetch it back
IRiakObject myData = myBucket.fetch("key1").execute();
// you can specify extra parameters to the store operation using the
// fluent builder style API
myData = myBucket.store("key1", "value2").returnBody(true).execute();
// delete
myBucket.delete("key1").rw(3).execute();
有谁在使用
GitHub,一个开源代码库以及版本控制系统,是管理软件开发以及发现已有代码的首选方法,在GitHub,用户可以十分轻易地找到海量的开源代码。
BestBuy ,百思买集团(Best Buy),全球最大家用电器和电子产品零售集团。
- Redis
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。Redis支持存储的value类型包括 string(字符串)、hash(散列)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add /remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。Redis数据都是缓存在 内存中,会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Jedis 是 Redis 官方首选的 Java 客户端开发包。
有谁在使用
Twitter (Redis和Memcached),一家美国社交网络及微博客服务的网站,是全球互联网上访问量最大的十个网站之一。是一个广受欢迎的社交网络及微博客服务的网站。
StackOverFlow ,是一个与程序相关的IT技术问答网站。用户可以在网站免费提交问题,浏览问题,索引相关内容。是程序员经常光顾的网站之一。
Instagram,是一款支持iOS、Windows Phone、Android平台的移动应用,允许用户在任何环境下抓拍下自己的生活记忆,选择图片的滤镜样式,一键分享至Instagram、 Facebook、Twitter、Flickr、Tumblr、foursquare或者新浪微博平台上。不仅仅是拍照,作为一款轻量级但十分有趣的 App,Instagram 在移动端融入了很多社会化元素,包括好友关系的建立、回复、分享和收藏等,这是Instagram 作为服务存在而非应用存在最大的价值。
**Flick**r,雅虎旗下图片分享网站。为一家提供免费及付费数位照片储存、分享方案之线上服务,也提供网络社群服务的平台。其重要特点就是基于社 会网络的人际关系的拓展与内容的组织。这个网站的功能之强大,已超出了一般的图片服务,比如图片服务、联系人服务、组群服务。
暴雪,大名鼎鼎的游戏公司。
新浪、街旁、知乎等。
- Memcached
Memcached 是一个基于一个存储键/值对的高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。
许多Web 应用程序都将数据保存到RDBMS中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大,访问的集中,就会出现RDBMS的负担加重,数据库 响应恶化,网站显示延迟等重大影响。Memcached是高性能的分布式内存缓存服务器。一般的使用目的是通过缓存数据库查询结果,减少数据库的访问次 数,以提高动态Web 应用的速度、提高扩展性。如图2所示。
图2Memcached-Java-Client 是一个memcached Java客户端API,应用广泛,运行比较稳定。XMemcached也使用得比较广泛,而且有较详细的中文API文档,具有如下特点:高性 能、支持完整的协议、支持客户端分布、允许设置节点权重、动态增删节点、支持JMX、与Spring框架和Hibernate-memcached的集 成、客户端连接池、可扩展性好等。
有谁在使用
Twitter (Redis和Memcached)
Youtube ,世界上最大的视频网站。
Wikipedia,维基百科是一个基于维基技术的多语言百科全书协作计划,用多种语言编写的网络百科全书。
WordPress.com,WordPress是一款个人博客系统,并逐步演化成一款内容管理系统软件,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站,也可以把 WordPress当作一个内容管理系统(CMS)来使用。
二、面向文档(Document-Oriented)数据库
面向文档数据库会将数据以文档的形式储存。每个文档都是自包含的数据单元,是一系列数据项的集合。每个数据项都有一个名称与对应的值,值既可以是简 单的数据类型,如字符串、数字和日期等;也可以是复杂的类型,如有序列表和关联对象。数据存储的最小单位是文档,同一个表中存储的文档属性可以是不同的, 数据可以使用XML、JSON或者JSONB等多种形式存储。
数据结构要求不严格,表结构可变,不需要像关系型数据库一样需要预先定义表结构,但是查询性能不高,而且缺乏统一的查询语法。
适用的场景
1. 日志。企业环境下,每个应用程序都有不同的日志信息。Document-Oriented数据库并没有固定的模式,所以我们可以使用它储存不同的信息。
2. 分析。鉴于它的弱模式结构,不改变模式下就可以储存不同的度量方法及添加新的度量。
不适用场景
在不同的文档上添加事务。Document-Oriented数据库并不支持文档间的事务,如果对这方面有需求则不应该选用这个解决方案。
产品:MongoDB、CouchDB、RavenDB、Terrastore 、OrientDB
- MongoDB
MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。是一个介于关系数据库和非关 系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂 的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功 能,而且还支持对数据建立索引。
mongoDB对Java支持的驱动包常用的是mongodb-java-driver,另外还有Mopa4j ,全称是 MOngo Persistence API for Java,它将 POJO 映射到 com.mongodb.DBObject,反之也可以。
有谁在使用
Craiglist上使用MongoDB的存档数十亿条记录。
FourSquare,基于位置的社交网站,在Amazon EC2的服务器上使用MongoDB分享数据。
Shutterfly,以互联网为基础的社会和个人出版服务,使用MongoDB的各种持久性数据存储的要求。
bit.ly, 一个基于Web的网址缩短服务,使用MongoDB的存储自己的数据。
spike.com,一个MTV网络的联营公司, spike.com使用MongoDB的。
Intuit公司,一个为小企业和个人的软件和服务提供商,为小型企业使用MongoDB的跟踪用户的数据。
sourceforge.net,资源网站查找,创建和发布开源软件免费,使用MongoDB的后端存储。
etsy.com ,一个购买和出售手工制作物品网站,使用MongoDB。
纽约时报,领先的在线新闻门户网站之一,使用MongoDB。
CERN,著名的粒子物理研究所,欧洲核子研究中心大型强子对撞机的数据使用MongoDB。
- CouchDB
CouchDB 是一个开源的面向文档的数据库管理系统,它提供以 JSON 作为数据格式的 REST 接口来对其进行操作,并可以通过视图来操纵文档的组织和呈现。术语 “Couch” 是 “Cluster Of Unreliable Commodity Hardware” 的首字母缩写,它反映了 CouchDB 的目标具有高度可伸缩性,提供了高可用性和高可靠性,即使运行在容易出现故障的硬件上也是如此。
CouchDB是分布式的数据库,它可以把存储系统分布到n台物理的节点上面,并且很好的协调和同步节点之间的数据读写一致性。这当然也得靠Erlang 无与伦比的并发特性才能做到。对于基于web的大规模应用文档应用,分布式可以让它不必像传统的关系数据库那样分库拆表,在应用代码层进行大量的改动。
CouchDB是面向文档的数据库,存储半结构化的数据,比较类似lucene的index结构,特别适合存储文档,因此很适合CMS,电话本,地址本等应用,在这些应用场合,文档数据库要比关系数据库更加方便,性能更好。
CouchDB支持REST API,可以让用户使用JavaScript来操作CouchDB数据库,也可以用JavaScript编写查询语句,我们可以想像一下,用AJAX技术结合CouchDB开发出来的CMS系统会是多么的简单和方便。
CouchDB 的 JDBC 驱动程序是jcouchdb ,这是一个经过良好测试并且易于使用的Java库,它会自动地将Java对象序列化、反序列化进CouchDB数据库。选择jcouchdb的另一个原因是它和CouchDB自身的API非常相似。 - RavenDB
RavenDB是基于Windows/.NET平台的NoSQL数据库,支持Linq的开源文档数据库,旨在Window平台下提供一个高性能,结构简单,灵活,可扩展NoSQL存储。Raven将JSON文档存在数据库中。可以使用C#的Linq语法查询数据。
NBC News,美国国家广播公司使用了RavenDB。 - Terrastore
Terrastore 是一个基于Terracotta(一 个业界公认的、快速的分布式集群组件)实现的高性能分布式文档数据库。可以动态从运行中的集群添 加/删除节点,而且不需要停机和修改任何配置。支持通过http协议访问Terrastore。Terrastore提供了一个基于集合的键/值接口来管 理JSON文档并且不需要预先定义JSON文档的架构。易于操作,安装一个完整能够运行的集群只需几行命令。 - OrientDB
OrientDB 是兼具文挡数据库的灵活性和图形数据库管理链接 能力的可深层次扩展的文档-图形数据库管理系统。可选无模式、全模式或混合模式下。支持许 多高级特性,诸如ACID事务、快速索引,原生和SQL查询功能。可以JSON格式导入、导出文档。若不执行昂贵的JOIN操作的话,如同关系数据库可在 几毫秒内可检索数以百记的链接文档图。
三、 列存储(Wide Column Store/Column-Family)数据库
列存储数据库将数据储存在列族(column family)中,一个列族存储经常被一起查询的相关数据。举个例子,如果我们有一个Person类,我们通常会一起查询他们的姓名和年龄而不是薪资。这种情况下,姓名和年龄就会被放入一个列族中,而薪资则在另一个列族中。
列存储查找速度快,可扩展性强,更容易进行分布式扩展,适用于分布式的文件系统。
适用的场景
1. 日志。因为我们可以将数据储存在不同的列中,每个应用程序可以将信息写入自己的列族中。
2. 博客平台。我们储存每个信息到不同的列族中。举个例子,标签可以储存在一个,类别可以在一个,而文章则在另一个。
不适用场景
1. 如果我们需要ACID事务。Vassandra就不支持事务。
2. 原型设计。如果我们分析Cassandra的数据结构,我们就会发现结构是基于我们期望的数据查询方式而定。在模型设计之初,我们根本不可能去预测它的查询方式,而一旦查询方式改变,我们就必须重新设计列族。
产品:Cassandra、HBase
- Cassandra
Cassandra是一套开源分布式NoSQL数据库系统,是一个混合型的非关系的数据库,以Amazon专有的完全分布式的Dynamo为基础,结合了 Google BigTable基于列族(Column Family)的数据模型。Cassandra的主要特点就是它不是一个数据库,而是由一堆数据库节点共同构成的一个分布式网络服务,对 Cassandra 的一个写操作,会被复制到其他节点上去,对Cassandra的读操作,也会被路由到某个节点上面去读取。对于一个Cassandra群集来说,扩展性能 是比较简单的事情,只管在群集里面添加节点就可以了。和其他数据库比较,有三个突出特点:模式灵活、可扩展性、多数据中心。
使用官方java驱动操作cassandra 非常简单。
有谁在使用
Ebay ,(EBAY,中文电子湾、亿贝、易贝)是一个管理可让全球民众上网买卖物品的线上拍卖及购物网站。
Instagram ,是一款支持iOS、Windows Phone、Android平台的移动应用,允许用户在任何环境下抓拍下自己的生活记忆,选择图片的滤镜样式,一键分享至Instagram、 Facebook、Twitter、Flickr、Tumblr、foursquare或者新浪微博平台上。
NASA,如雷贯耳,美国国家航空航天局。
Twitter ,(Cassandra and HBase)全世界都非常流行的社交网络及微博客服务的网站。
- HBase
HBase,Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。HBase是Apache的Hadoop项目的子项目。HBase不同于一般的关系数据库,它是一个适合于非 结构化数据存储的数据库。另一个不同的是HBase基于列的而不是基于行的模式。Apache三剑客:HBase, Cassandra, CouchDB,HBase的前景最为看好,因为它的开发者众多并且都是顶尖高手。
图3描述Hadoop EcoSystem中的各层系统。其中,HBase位于结构化存储层,Hadoop HDFS为HBase提供了高可靠性的底层存储支持,Hadoop MapReduce为HBase提供了高性能的计算能力,Zookeeper为HBase提供了稳定服务和failover机制。Pig和Hive还为 HBase提供了高层语言支持,使得在HBase上进行数据统计处理变的非常简单。 Sqoop则为HBase提供了方便的RDBMS数据导入功能,使得传统数据库数据向HBase中迁移变的非常方便。
图3
HBase提供的访问接口有:
1. Native Java API,最常规和高效的访问方式,适合Hadoop MapReduce Job并行批处理HBase表数据
2. HBase Shell,HBase的命令行工具,最简单的接口,适合HBase管理使用
3. Thrift Gateway,利用Thrift序列化技术,支持C++,PHP,Python等多种语言,适合其他异构系统在线访问HBase表数据
4. REST Gateway,支持REST 风格的Http API访问HBase, 解除了语言限制
5. Pig,可以使用Pig Latin流式编程语言来操作HBase中的数据,和Hive类似,本质最终也是编译成MapReduce Job来处理HBase表数据,适合做数据统计
6. Hive,支持HBase,可以使用类似SQL语言来访问HBase
有谁在使用
Twitter,全世界都非常流行的社交网络及微博客服务的网站。
Facebook,美国的一个社交网络服务网站。
Yahoo!,美国著名的互联网门户网站,也是20世纪末互联网奇迹的创造者之一。其服务包括搜索引擎、电邮、新闻等,业务遍及24个国家和地区,为全球超过5亿的独立用户提供多元化的网络服务。同时也是一家全球性的因特网通讯、商贸及媒体公司。
四、 图(Graph-Oriented)数据库
图数据库允许我们将数据以图的方式储存。实体会被作为顶点,而实体之间的关系则会被作为边。比如我们有三个实体,Steve Jobs、Apple和Next,则会有两个“Founded by”的边将Apple和Next连接到Steve Jobs。
主要用于社交网络,推荐系统等。专注于构建关系图谱。
适用的场景
1. 在一些关系性强的数据中
2. 推荐引擎。如果我们将数据以图的形式表现,那么将会非常有益于推荐的制定
不适用场景
不适合的数据模型。图数据库的适用范围很小,因为很少有操作涉及到整个图。
产品:Neo4J、Infinite Graph、OrientDB
- Neo4J
Neo4J是一个高性能的,NOSQL图形数据库,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java 持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有 特性。程序员工作在一个面向对象的、灵活的网络结构下而不是严格、静态的表中——但是他们可以享受到具备完全的事务特性、企业级的数据库的所有好处。它的 架构图如图4所示。
图4
neo4j连接java目前主要有嵌入式、jdbc和rest api。
有谁在使用
Adobe,是世界领先数字媒体和在线营销方案的供应商,Adobe 的客户包括世界各地的企业、知识工作者、创意人士和设计者、OEM 合作伙伴,以及开发人员。
Cisco,全球领先的网络解决方案供应商。
T-Mobile,是一家跨国移动电话运营商,是世界上最大的移动电话公司之一。
- Infinite Graph
InfiniteGraph企业分布式图形数据库具有可伸缩性,它还能够在大量多地存储的复杂数据中,为大型企业执行实时搜索。通过使用图算法,它为分析应用程序添加了新的价值,以发现和存储新的连接和关系。
InfiniteGraph需要作为服务项目加以安装,这与以MySQL为代表的传统数据库颇为相似。InfiniteGraph借鉴了 Objectivity/DB中的面向对象概念,因此其中的每一个节点及边线都算作一个对象。InfiniteGraph还提供了一套可视化工具用以查看 数据。
InfiniteGraph基于Java实现,它的目标是构建“分布式的图形数据库”,已被美国国防部和美国中央情报局所采用。
Redis介绍
目前主流的NoSQL数据库,基于键值的Redis占一席之地,它功能丰富,交互简单,适用场景多。
Redis,全称Remote Dictionary Server,远程字典服务器, Redis是一个开源的、高性能的、基于键值对的缓存与存储系统,通过提供多种键值数据类型来适应不同场景下的缓存与存储需求。它以字典结构存储数据,并 允许其他应用通过TCP协议读写字典中的内容。
Redis数据库中的数据是保存在内存中的,因此它的性能比基于硬盘存储的数据库有明显的优势,同时redis提供了对持久化的支持,可以将内存中的数据异步写入到硬盘中。
即使不采取redis作为应用数据库,选择redis作为缓存、队列系统,也是一个不错的选择。
Redis目前支持的键值数据类型如下:
字符串类型(string)
散列类型(hash)
列表类型(list)
集合类型(set)
有序集合类型(zset/sorted_set)
一个Redis实例相当于一格书架,书架里有16本字典(独立数据库),默认从0开始编号,查找最后一本字典的命令是select 15,通过select number可以自由切换数据库,这16个库并非完全隔离,某些命令可以通用,同时redis不支持自定义数据库名和访问密码,所有16个库的访问权限是 一致的。区别于oracle的实例,所以不同的应用应该使用不同的redis实例。
http://www.techug.com/nosql