初探 Nosql : 列举两个简略的比如

第一个示例创立一个简略的方位首选项存储,第二个示例管理汽车品牌和模型数据库。这两个示例都侧重于与NoSQL上下文相关的数据管理方面。

示例一 : 创立一个简略的方位首选项存储

随着当地企业企图与邻近的用户树立联络,以及大公司企图依据人们驻守的方位定制他们的在线体会和产品,根据方位的服务正变得越来越突出。在盛行的应用程序中能够看到一些常见的根据方位的偏好,例如Google地图,它答应本地查找,以及在线零售商(如 Walmart.com)依据离您最近的沃尔玛商铺方位供给产品可用性和促销信息。

有时要求用户输入方位数据,有时揣度用户方位。推理能够根据用户的 IP 地址、网络接入点(特别是当用户从移动设备拜访数据时)或这些技能的恣意组合。无论数据是怎么搜集的,您都需求有效地存储它,这便是示例开端的当地。

为简略起见,仅在美国为用户保护方位首选项,因而只需用户标识符和邮政编码即可查找用户的方位。让我们从用户名作为其标识符开端。需求保护“John Doe,10001”、“Lee Chang,94129”、“Jenny Gonzalez 33101”和“Srinivas Shastri, 02101”等数据点。

为了以灵敏且可扩展的办法存储此类数据,此示例运用名为 MongoDB 的非联系数据库产品。在接下来的几个过程中,您将创立一个MongoDB数据库并存储一些示例方位数据点。

发动MongoDB并存储数据

假设您已成功装置MongoDB,请发动服务器并衔接到它。

您能够经过在发行版的 bin 文件夹中运转 mongod 程序来发动 MongoDB 服务器。发行版因底层环境而异,能够是 Windows、Mac OS X 或 Linux ,但在每种情况下,服务器程序都具有相同的称号,而且它驻留在发行版中名为 bin 的文件夹中。

衔接到MongoDB服务器的最简略办法是运用发行版中可用的JavaScript shell。只需从指令行界面运转 mongo。mongo JavaScript shell 指令也能够在 bin 文件夹中找到。

当您经过运转mongod发动MongoDB服务器时,您应该在操控台上看到类似于以下内容的输出:

使用两个例子玩转NoSQL

当 mongod 经过 Windows PowerShell 运转时,此特定输出是在 Windows 7 64 位核算机上捕获的。依据您的环境,您的输出或许会有所不同。

现在数据库服务器现已发动并运转,请运用 mongo JavaScript shell 衔接到它。外壳的初始输出应如下所示:

使用两个例子玩转NoSQL

默许情况下,mongo shell 衔接到本地主机上可用的“test”数据库。从 mongod(服务器看护程序)操控台输出中,您还能够猜测 MongoDB 服务器在端口 27017 上等候衔接。要探究一组或许的初始指令,只需在 mongo 交互式操控台上键入 help。键入协助并按 Enter 键(或 Return)键时,您应该会看到如下指令选项列表:

使用两个例子玩转NoSQL

自界说 MONGODB 数据目录和端口

默许情况下,MongoDB将数据文件存储在/data/db(Windows上的c:\data\db)目录中,并侦听端口27017上的恳求。您能够经过运用 dbpath 选项指定目录途径来指定备用数据目录,如下所示:

mongod--dbpath /path/to/alternative/directory

使用两个例子玩转NoSQL

假如数据目录尚不存在,请保证已创立该目录。此外,请保证 mongod 有权写入该目录。

此外,您还能够经过显式传递端口来指示MongoDB侦听备用端口上的衔接,如下所示:

mongod --port 94301

为防止抵触,请保证端口未在运用中。

要一起更改数据目录和端口,只需一起指定 –dbpath 和 –port 选项以及 mongod 可履行文件的相应代替值。


接下来,您将学习怎么在MongoDB实例中创立首选项数据库。

创立首选项数据库

首要,创立一个名为 prefs 的首选项数据库。创立后,将username和zip code的元组(或对)存储在此数据库内的名为 location 的调集中。然后将可用的数据集存储在此界说的结构中。在MongoDB术语中,它将转化为履行以下过程:

  1. 切换到首选项数据库。

  2. 界说需求存储的数据集。

  3. 将界说的数据集保存在名为方位的调集中。

要履行这些过程,请在 Mongo JavaScript 操控台上键入以下内容:

use prefs
w = {name: "John Doe", zip: 10001}; 
x = {name: "Lee Chang", zip: 94129};
y = {name:"Jenny Gonzalez", zip: 33101); 
z = {name: "Srinivas Shastri", zip: 02101}; 
db.location.save(w);
db.location.save(x);
db.location.save(y); 
db.location.save(z);

便是这样!几个简略的过程,数据存储就准备就绪。不过,在持续之前有一些快速阐明:

use prefs 指令将当时数据库更改为名为 prefs 的数据库。

可是,从未显式创立数据库自身。同样,经过将数据点传递给数据库,将数据点存储在方位调集中。

location.save()办法.该调集也不是显式创立的。在MongoDB中,只要在将数据刺进其间时,才会创立数据库和调集。因而,在此示例中,它是在刺进第一个数据点(称号:“John Doe”,zip:10001})时创立的。

现在能够查询新创立的数据库以验证存储的内容。若要获取存储在名为 location 的调集中的所有记载,请运转 db.location.find()。

运转数据库 db.location.find()显示以下输出:

使用两个例子玩转NoSQL

核算机上的输出应类似。仅有会改动的是 objectId。ObjectId是MongoDB用MongoDB术语仅有标识每个记载或文档的办法。

MongoDB运用Objectid仅有地标识调集中的每个文档。文档的目标标识存储为该文档the_id特点。
刺进记载时,能够将任何仅有值设置为目标 Id,该值的仅有性需求由开发人员保证。
还能够防止在刺进记载时指定 _id 特点的值。
在这种情况下,MongoDB会创立并刺进一个适当的仅有ID。MongoDB中生成的这种id是BSON,二进制JSON的缩写,格局最好总结如下:
    BSON 目标 ID 是一个 12 字节的值。

    前 4 个字节表明创立时间戳。它表明自纪元以来的秒数。此值有必要存储在大字节序中,这意味着序列中最重要的值有必要存储在最低存储地址中。

    接下来的 3 个字节表明核算机 ID。以下 2 个字节表明进程 ID。

    最终 3 个字节表明计数器。此值有必要存储在大端序中。

    BSON 格局除了保证仅有性外,还包含创立时间戳。所有规范MongoDB驱动程序都支撑BSON格局ID。

不带参数的 find 办法回来调集中的所有元素。在某些情况下,这或许不可取,或许只需求调集的子集。若要了解查询或许性,请将以下附加记载添加到方位调集:

使用两个例子玩转NoSQL

您能够经过 mongo shell 完结此操作,如下所示:

使用两个例子玩转NoSQL

要仅获取 10001 邮政编码中的人员的列表,您能够按如下办法查询:

>db.location.find({zip10001));
{ “_id” : objectId(“4c97053abe67000000003857”), “name”:“John Doe”,“zip”:10001}
{ “_id” : objectid(“4c97a6555c760000000054d8”), “name” : “Don Joe”, “zip”:10001}

要取得所有称号为“John Doe”的人的列表,您能够像这样查询:

>db.location.find({name:“John Doe”});
{“_id” : ObjectId(“4c97053abe67000000003857”), “name” : “John Doe”, “zip”:10001}
{ “_id” : ObjectId(“4c97a7ef5c760000000054da”),“name” : “John Doe”, “zip” : 94129}

在挑选调集的两个查询中,查询文档作为参数传递给 find 办法。查询文档指定需求匹配的键和值的形式。MongoDB支撑许多高档查询机制,而不仅仅是简略的过滤器,包含借助正则表达式的形式表明。

由于数据库包含较新的数据集,因而调集的结构或许会成为约束,因而需求修正。在传统的联系数据库意义上,您或许需求更改表架构。在联系数据库中,更改表形式还意味着承当杂乱的数据搬迁使命,以保证新旧架构中的数据一起存在。

在MongoDB中,修正调集结构是微不足道的。更精确地说,调集(类似于表)是无架构的,因而它答应您在同一调集中存储不同的文档类型。

参考一个示例,您需求存储另一个用户的方位首选项,该用户的称号和邮政编码与数据库中已存在的文档相同,例如另一个({name:“Lee Chang”,zip:94129})。当然,有意和不现实地假设称号和 zip 对是仅有的!

为了从数据库中的第二个Lee Chang中区别出第二个Lee Chang,添加了一个附加特点,即街道地址,如下所示:

使用两个例子玩转NoSQL

现在,运用 find 获取所有文档,回来以下数据集:

>db.location.find();
{“_id” : ObjectId(“4c97053abe67000000003857”), “name”:“John Doe”, “zip” :10001 }
{ “_id” : objectId(“4c970541be67000000003858”), “name” : “Lee Chang”, “zip”:94129}
(“_id” : objectId(“4c970548be67000000003859”), “name” : “Jenny Gonzalez”, “zip” :33101 }
{“_id” : objectId(“4c970555be6700000000385a”), “name” : “Srinivas Shastri”, “zip”:1089}
{“_id” : objectId(“4c97a6555c760000000054d8”), “name” :“Don Joe”, “zip”:10001}
{ “_id” : objectId(“4c97a7ef5c760000000054da”), “name” :“John Doe”, “zip”:94129}
{“_id” : ObjectId(“4c97add25c760000000054db”), “name” : “Lee Chang”, “zip” : 94129, “streetAddress” : “37000 Graham Street”)

您能够从大多数干流编程言语拜访此数据集,由于存在这些驱动程序。

示例二:存储汽车品牌和类型数据

此示例中运用了分布式列族数据库 Apache Cassandra。

Apache Cassandra 是一个分布式数据库,因而您在运用此产品时一般会设置数据库集群。对于此示例,经过将 Cassandra 作为单个节点运转来防止设置集群的杂乱性。在生产环境中,您不需求这样的装备,但您现在只是在试水并了解基础知识,因而单个节点就足够了。

Cassandra数据库能够经过简略的指令行客户端或经过Thrift接口进行接口。Thrift接口协助各种编程言语衔接到Cassandra。从功用上讲,您能够将 Thrift 接口视为通用的多言语数据库驱动程序。

持续运用汽车品牌和模型数据库,首要发动Cassandra并衔接到它。

发动 Cassandra 并衔接到它

您能够经过从提取 Cassandra 压缩(tarred 和 gzipped)发行版的文件夹中调用 bin/cassandra 来发动 Cassandra 服务器。对于此示例,运转 bin/ Cassandra-f-f 选项使 Cassandra 在前台运转。这会在您的机器上本地发动一个 Cassandra 节点。作为群集运转时,将发动多个节点,并将这些节点装备为彼此通讯。对于此示例,一个节点足以阐明在 Cassandra 中存储和拜访数据的基础知识。

发动 Cassandra 节点时,您应该在操控台上看到如下输出:

使用两个例子玩转NoSQL

特定的输出来自我的Windows 7 64位机器,当Cassandra可履行文件从Windows PowerShell运转时。假如您运用不同的操作体系和不同的 shell,您的输出或许会略有不同。

运转 APACHE CASSANDRA 节点

Apache Cassandra 存储装备在 conf/cassandra.yaml 中界说。当您下载并提取以压缩的 tar.gz 格局供给的 Cassandra 稳定版或开发发行版时,您将取得一个 Cassandra。具有某些默许装备的 yaml 文件。例如,它希望提交日志坐落 /var/lib/cassandra/commitlog 目录中,数据文件坐落 /var/lib/cassandra/data 目录中。此外,Apache Cassandra 运用 log4j 进行日志记载。

Cassandra log4j 能够经过 conf/log4j-server .properties 进行装备。默许情况下,Cassandra log4j 希望将日志输出写入 /var/log/ cassandra/system.log。假如要保存这些默许值,请保证这些目录存在,而且您具有拜访和写入它们的适当权限。假如要修正此装备,请保证在相应的日志文件中指定您挑选的新文件夹。

在我的示例中,从conf/cassandra.yaml提交日志和数据目录特点是:


# directories where Cassandra should store data on disk.
data_file_directories:
    -/var/lib/cassandra/data
# commit log
commitlog_directory: 
    /var/lib/cassandra/commitlog

cassandra.yaml 中的途径值不需求以 Windows 的格局指定。例如,您不需求将提交日志途径指定为

commitlog_directory: c:\var\lib\cassandra\commitlog.

在我的示例中,来自 conf/log4j-server.properties 的 log4j 追加器文件装备是:

log4j.appender.R.File=/var/log/cassandra/system.log

衔接到核算机上正在运转的 Cassandra 节点的最简略办法是运用Cassandra 指令行界面 (CLI)。

发动指令行就像运转 bin/ Cassandra-cli 相同简略。您能够将主机和端口特点传递给 CLI,如下所示:

bin/cassandra-cli-host localhost -port 9160

运转 cassandra-cli 的输出如下:

使用两个例子玩转NoSQL

要获取可用指令的列表,请键入 help 或 ?您将看到以下输出:

使用两个例子玩转NoSQL

将列表成果限制为 N。现在您现已了解了 Cassandra 基础知识,您能够持续为汽车品牌和类型数据创立存储界说,并将一些示例数据刺进并拜访到这个新的 Cassandra 存储计划中。

运用 Cassandra 存储和拜访数据

首要要了解密钥空间和列系列的概念。键空间和列族最接近的联系数据库并行是数据库和表。虽然这些界说并不完全精确,有时乃至具有误导性,但它们是了解密钥空间和列族运用的杰出起点。随着您了解基本的运用形式,您将对这些概念有更深入的赏识和了解,这些概念超出了它们的联系类似之处。

首要,列出 Cassandra 服务器中的现有密钥空间。转到 cassandra-cli,键入 show keyspaces 指令,然后按 Enter 键。由于您正在重新装置 Cassandra,所以您或许会看到类似于以下内容的输出:

使用两个例子玩转NoSQL

望文生义,体系密钥空间就像 RDBM 中的管理数据库。体系键空间包含一些预界说的列系列。

键空间将列族组合在一起。一般,每个应用程序界说一个密钥空间。数据复制在密钥空间级别界说。这意味着数据的冗余副本的数量以及这些副本的存储办法是在密钥空间级别指定的。

Cassandra 发行版在一个名为 schema-sample.txt 的文件中附带了一个示例键空间创立脚本,该文件在 conf 目录中可用。您能够按如下办法运转示例密钥空间创立脚本:

PS C:\applications\apache-cassandra-0.7.4>.\bin\cassandra-cli -host localhost --file.\conf\schema-sample.txt

再次经过指令行客户端衔接,并在界面中重新发出 show keyspaces 指令。这次的输出应该是这样的:

使用两个例子玩转NoSQL
使用两个例子玩转NoSQL

接下来,运用示例中的脚本在此密钥空间中创立 CarDataStore 密钥空间和 Cars 列系列。

schema-cardatastore.txt:

/*schema-cardatastore.txt*/
create keyspace CarDataStore
    with replication_factor=1
    and placement_strategy = 'org. apache. cassandra. locator. SimpleStrategy' ; 
use CarDatastore;
create column family Cars 
    with comparator=UTF8Type
    and read_repair_chance=0.1 
    and keys_cached=100
    and gc_grace=0
    and min_compaction_threshold=5
    and max_compaction_threshold=31;

您能够运转schema-cardatastore.txt脚本,如下所示:

PS C:\applications\apache-cassandra-0.7.4> bin/cassandra-cli -host localhost --file c:\workspace\nosql\examples\schema-cardatastore.txt

您已成功添加新的密钥空间!回来到脚本并简要回顾怎么添加密钥空间。您添加了一个名为 carDatastore 的密钥空间。您还在此密钥库中添加了一个名为 columnFamily 的工件。ColumnFamily的名字是Cars.你稍后会看到ColumnFamily的运转,但现在把它们想象成表格,在ColumnFamily标签中,还包含一个名为 comparewith 的特点。比较的值被指定为 UTF8Type。Comparewith特点值影响行键的索引和排序办法。。密钥空间界说中的其他符号指定复制选项。CarDataStore 的复制因子为 1,这意味着 Cassandra 中只存储了一个数据副本。

接下来,将一些数据添加到 CarDataStore 密钥空间,如下所示:

 [defaulteunknown] use CarDatastore;
Authenticated to keyspace:CarDatastore
[default@CarDatastore] set Cars['Prius']['make'] = 'toyota';
Value inserted.
[defaulteCarDatastore] set Cars['Prius']['model'] = 'prius 3'; Value inserted.
[default@CarDataStore] set Cars['Corolla']['make'] ='toyota'; Value inserted.
[default@carDatastore] set Cars['Corolla']['model']='le'; Value inserted.
[defaulteCarDataStore] set Cars['fit']['make'] = 'honda'; Value inserted.
[defaulteCarDataStore] set Cars['fit']['model'] = 'fit sport'; Value inserted.
[defaulteCarDataStore] set Cars['focus']['make'] Value inserted.
[default@CarDataStore] set Cars['focus']['model']= Value inserted.

图示的指令集是将数据添加到 Cassandra 的一种办法。运用此指令,在行中添加称号-值对或列值,而行又在键空间的列系列中界说。例如,设置 Cars['Prius']['make'] = 'toyota',一个称号-值对:“make”= 'toyota' 被添加到一行中,该行由键“Prius”标识。Prius标识的行是“car”列系列的一部分。“car”列系列是在 CarDatastore 中界说的,您知道它是密钥空间。

添加数据后,能够查询和检索它。要获取Prius标识的行的称号-值对或列名和值,请运用以下指令:获取Cars['Prius']。输出应如下所示:


[default @ CarDatastore] get Cars['Prius'];
= > (column=make, value=746f796f7461, timestamp=1301824068109000)
= > (column=model, value=70726975732033, timestamp=1301824129807000)
Returned 2 results.

构造查询时要当心,由于行键、列系列标识符和列键区别大小写。因而,传入“prius”而不是“Prius”不会回来任何称号值元组。尝试经过 CLI 运转获取Cars['Prius']。您将收到一个呼应,内容为“Returned 0 results”。此外,在查询之前,请记住发出运用 CarDatastore 使 CarDatastore 成为当时密钥空间。

要仅拜访“Prius”行的“make”称号-值数据,您能够像这样查询:

[default@CarDataStore] get Cars['Prius']['make'];
=>(column=make,value=746f796f7461, timestamp=1301824068109000)

Cassandra 数据集能够支撑比目前显示的更丰厚的数据模型,查询功用也比所示的更杂乱,

在浏览了两个简略的示例之后,一个触及文档存储 MongoDB,另一个触及列数据库 Apache Cassandra,您或许现已准备好运用您挑选的编程言语开端与这些示例进行交互。


本文正在参与「技能专题19期 闲谈数据库技能」活动