上一篇简单描述了一下SequoiaDB的简单CRUD操作,本篇将讲述一下稍微高级点的功能。

部署在我机器上的集群环境,在经过创建名字为"foo"的cs,创建名字为"bar"的cl,以及插入一些数据之后,并没有删除掉,因此在本篇中会继续使用。

首先,我们先看看,在SequoiaDB的安装目录中的database目录里面,有那些文件:

~$ ls /opt/sequoiadb/database/data/11850

我们会发现有几个文件:foo.1.idxfoo.1.data

正好是我们创建的cs的名字。是不是巧合呢?

验证一下,依次做以下操作:

  • 启动两个终端:终端1,终端2;
  • 在终端1中,进入SequoiaDB的shell执行环境;
  • 连接上数据库。

以上我不再写出操作,读者可以自己操作一下,有利于熟悉常用操作。

先删除Collection Space,执行:

> db.dropCS("foo")

然后在终端2下,查看一下文件:

~$ ls /opt/sequoiadb/database/data/11850

这个时候,我们发现foo.1.datafoo.1.idx文件没有了。

再回到终端1,重新创建名为“foo”的cs:db.createCS("foo")

切换到终端2,再次查看文件:

~$ ls /opt/sequoiadb/database/data/11850

这个时候,foo.1.datafoo.1.idx文件又有了。

因此,我们基本可以确定,一个cs对应一个.data文件和一个.idx文件;cl是data文件下的逻辑概念,相当于是关系数据库中的table。故在操作文件的时候,请谨慎,不是不得已,不要动这些*.data*.idx 文件

上面算是一点积累,准备进入本篇的正题:

因为上面的操作删除掉了cs,然后重新创建了名为"foo"的cs(虽然名字一样,但是删除过一次,里面的内容已经没有了)。所以再次创建名为"bar"的cl。

再切换到终端1,创建cl:

> db.foo.createCL("bar")

先构造一些数据:

> docs = [
... {"name":"Milky", "age":24},
... {"name":"Jim", "age":23, "ip":"192.168.1.131"},
... {"name":"Tyle", "age":24, "phone":"10086"},
... {"name":"Tony","age":33 } ]

插入数据:

> db.foo.bar.insert( docs )

一、创建索引

  有时候数据很多,但是想尽快查询到特定的数据,这个时候,就需要用到索引了。

  在简历索引之前,先查询一下数据,并查看一下数据是通过普通扫描查询到的,还是通过索引扫描查询到的:

> db.foo.bar.find({"age": 24}).explain()

  结果是:

{
"Name": "foo.bar",
"ScanType": "tbscan",
"IndexName": "",
"UseExtSort": false,
"NodeName": "Milky:11860",
"ReturnNum": 0,
"ElapsedTime": 0.000003,
"IndexRead": 0,
"DataRead": 0,
"UserCPU": 0,
"SysCPU": 0
}

  然后创建一个索引:

> db.foo.bar.createIndex("ageIndex", {"age":1})

  然后我们再执行:

> db.foo.bar.find({"age": 24}).explain()

  结果是:

{
"Name": "foo.bar",
"ScanType": "ixscan",
"IndexName": "ageIndex",
"UseExtSort": false,
"NodeName": "Milky:11860",
"ReturnNum": 0,
"ElapsedTime": 0.000003,
"IndexRead": 0,
"DataRead": 0,
"UserCPU": 0,
"SysCPU": 0
}

  由于数据量太小,查询耗时对比都不太明显。但是在两次对比结果的“ScanType”字段的值中能看出一个走的tbscan,一个走的ixscan。如果有时间,可以试着插入万条级别的数据,再次试试,耗时的对比会比较明显。

二、删除索引

  这个就比较简单了。稍微演示一下:知道要删除的索引的名字是“ageIndex”,调用接口:

> db.foo.bar.dropIndex("ageIndex")

  再执行:

> db.foo.bar.find({"age": 24}).explain()

  结果是:

{
"Name": "foo.bar",
"ScanType": "tbscan",
"IndexName": "",
"UseExtSort": false,
"NodeName": "Milky:11860",
"ReturnNum": 0,
"ElapsedTime": 0.000003,
"IndexRead": 0,
"DataRead": 0,
"UserCPU": 0,
"SysCPU": 0
}

  此时的ScanType字段的值变成了“tbscan”,说明这次的查询,没有走索引:索引删除成功。

  一个好的索引,对dba来说,是一项牛逼的技能。关于如何创建一个高效的索引,已经超出本篇的范围,在此不做描述,请自行google学习。

三、记录条数计数

  这个操作也是一个很简单明了的操作。

  在以上操作的基础上,执行:

> db.foo.bar.count()

  返回:

4

  说明这个时候,cl中有四条数据(cl中的确是4条数据)。

四、聚集

  在SQL中,聚集是一个简单的语法。而在没有SQL语句的NoSQL中,就是aggregate来大显神威了。

  由于这块内容涉及到大量的匹配符等,我采用SequoiaDB官网给出的例子来演示:

  先构造数据:

> tom = {
... "no":1000,
... "score":80,
... "interest":["basketball", "football"],
... "major":"计算机科学与技术",
... "dep":"计算机学院",
... "info":{
... "name":"Tom",
... "age":25,
... "gender":"男"
... }
... } > sam = {
... "no":1000,
... "score":80,
... "interest":["music"],
... "major":"软件工程",
... "dep":"计算机学院",
... "info":{
... "name":"Sam",
... "age":22,
... "gender":"男"
... }
... }
> db.foo.bar.insert(tom)
> db.foo.bar.insert(sam)

  然后执行:

> db.foo.bar.aggregate({"$match":{"no":1000}}, {"$group":{"_id":"$major", "Major":{"$first":"$major"}, "avg_age":{"$avg":"$info.age"}}})

  输出结果:

{
"Major": "软件工程",
"avg_age": 22
}
{
"Major": "计算机科学与技术",
"avg_age": 25
}

  详细请参考SequoiaDB官网信息中心>>参考手册>>SequoiaDB Javascript方法>>SdbCollection>>db.collectionspace.collection.aggregate

  PS:有朋友私下问我,官网点进去,很难找到对应的位置。因为SequoiaDB官网的文档无法定位到确切的位置,所以只能索引到信息中心位置。很多需要慢慢看,如果熟悉一些数据库常用术语的话,定位会快一点。可以去SequoiaDB的社区吐槽哈,他们的社区地址是:SequoiaDB社区

五、切分

  对于每一条,有热数据与冷数据的区分。对于热数据,需要频繁访问;对于冷数据,可能访问的几率会比较小。因此,热数据所在的磁盘性能可能会更好一点。如果把冷数据和热数据都存放在性能好的磁盘上,会占据磁盘空间,由于不常访问,浪费了资源。因此热数据和冷数据通常要分开存放。

  这就是数据切分的由来了。

  SequoiaDB的数据切分需要用到两个数据组,把冷的数据,切分到另外一个组上。

  回顾第一篇部署集群环境的时候,已经就创建了一个数据组。在此,还需要创建另外一个组,组名叫“colddatagroup”。

  部署步骤,请参考 SequoiaDB系列之一:SequoiaDB的安装、部署

  先附切分原理图一张:

  

  现在,要创建一个新的名为"total"的cs,并在这个cs上创建一个名为"age"的cl,这个cl的分区键类型是"age",分区类型是"range"的:

> db.createCS("total")
localhost:11810.total
Takes 0.193840s.
> db.total.createCL("age", {"ShardingKey":{"age":1}, "ShardingType":"range"})
localhost:11810.total.hot
Takes 3.288509s.

  往这个cl中插入几条"age"的值不同的数据:

> docs = [
... {"age":20},
... {"age":21},
... {"age":22},
... {"age":23},
... {"age":50},
... {"age":60},
... {"age":62},
... {"age":68},
... {"age":79},
... {"age":85},
... {"age":90} ]
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Takes 0.42086s.

  插入数据:

> db.total.age.insert(docs)
Takes 0.2119s.

  然后定义一个规则,65岁之后的人,咱不管了,当冷数据处理。要把 age大于或等于65的,切分colddatagroup组上。输入:

> db.total.age.split("datagroup", "colddatagroup", {"age":65}, {"age":100})

  数据量很大的时候,这个操作耗时会有点长,耐心等待即可。

  等待操作完成,我们需要检验一下是否真的切分了。

  重新建立一个连接,这个连接比较特殊,因为这个连接是直接连接到某个数据节点上(还记得上一篇有一处提到的吗?生产环境下,不建议有这样操作)。

> node = new Sdb("Milky", 18800)

  这个节点是colddatagroup数据组上的节点,也是我们切分之后,存放age大于或等于65的数据的数据组中的数据节点。

  查看一下这个节点上有哪些cl:

> node.listCollections()

  结果显示的cl,名字整好是datagroup数据组上,用于切分的源数据组的collection的名字。

  查询一下:

> node.total.age.find()

  结果输出:

{
"_id": {
"$oid": "54ba9abe74b1303560000044"
},
"age": 68
}
{
"_id": {
"$oid": "54ba9abe74b1303560000045"
},
"age": 79
}
{
"_id": {
"$oid": "54ba9ca374b1303560000048"
},
"age": 80
}
{
"_id": {
"$oid": "54ba9abe74b1303560000046"
},
"age": 85
}
{
"_id": {
"$oid": "54ba9abe74b1303560000047"
},
"age": 90
}

  这些数据正是age字段的值,大于或者65的记录。

  如果还有疑问,可以再次直接连接到datagroup的数据组中的节点上,查询源数据组中的记录,检查是否其中的数据,age字段的值是否小于65。

至此,本篇也到了末尾结束部分,感谢您的耐心阅读!

下一篇,将进入本系列的重点部分,简析SequoiaDB的架构。敬请期待!

=====>THE END<=====

SequoiaDB 系列之三 :SequoiaDB的高级功能的更多相关文章

  1. SequoiaDB 系列源码分析调整

    犹豫我经验尚不够丰富,有大牛跟我说,以我这样定下的结构来分析源码,学习效果不太好. 应该先从程序的进程入口函数开始,慢慢的跟流程来分析.先通过系统的启动.退出来分析所用到的技术,像进程模型,线程模型等 ...

  2. SequoiaDB 系列之四 :架构简析

    在本系列的第一篇中,简述了SequoiaDB的安装,以及一个(伪)集群的部署 第二篇和第三篇对SequoiaDB的集群,做了简单地操作. 在本篇中,将对SequoiaDB的架构进行简单的分析. 因为自 ...

  3. SequoiaDB 系列之六 :源码分析之coord节点

    好久不见. 在上一篇SequoiaDB 系列之五   :源码分析之main函数,有讲述进程开始运行时,会根据自身的角色,来初始化不同的CB(控制块,control block). 在之前的一篇Sequ ...

  4. SequoiaDB 系列之五 :源码分析之main函数

    好久好久没有写博客了,因为一直要做各种事,工作上的,生活上的,这一下就是半年. 时光如梭. 这两天回头看了看写的博客,感觉都是贻笑大方. 但是还是想坚持把SequoiaDB系列写完. 初步的打算已经确 ...

  5. SequoiaDB 系列之二 :SequoiaDB的简单CRUD操作

    上一篇通过一系列的操作,终于把SequoiaDB的集群部署到单台机器上了. 建议去安装体验一下吧. 在整个环境的部署的体验来看,并没有MongoDB的部署简单,但是比MongoDB的部署要清晰.Mon ...

  6. SequoiaDB 系列之七 :源码分析之catalog节点

    这一篇紧接着上一篇SequoiaDB 系列之六 :源码分析之coord节点来讲 在上一篇中,分析了coord转发数据包到catalog节点(也有可能是data节点,视情况而定).这一次,我们继续分析上 ...

  7. SLAM+语音机器人DIY系列:(二)ROS入门——10.在实际机器人上运行ROS高级功能预览

    摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...

  8. Elasticsearch系列---几个高级功能

    概要 本篇主要介绍一下搜索模板.映射模板.高亮搜索和地理位置的简单玩法. 标准搜索模板 搜索模板search tempalte高级功能之一,可以将我们的一些搜索进行模板化,使用现有模板时传入指定的参数 ...

  9. Sql Server来龙去脉系列之三 查询过程跟踪

    我们在读写数据库文件时,当文件被读.写或者出现错误时,这些过程活动都会触发一些运行时事件.从一个用户角度来看,有些时候会关注这些事件,特别是我们调试.审核.服务维护.例如,当数据库错误出现.列数据被更 ...

随机推荐

  1. 有关Azure存储帐号监视器中的度量值

    在一次故障排错中,发现存储帐号监视器里'成功百分比'(该度量值的源选择的是blob)这个度量值始终是低于100%.引出几个问题: 1. 这个度量值所代表的意义? A: 存储基于REST协议,对服务的访 ...

  2. NP完全问题 NP-Completeness

    原创翻译加学习笔记,方便国人学习算法知识! 原文链接http://www.geeksforgeeks.org/np-completeness-set-1/ 我们已经找到很多很高效的算法来解决很难得问题 ...

  3. codeforces 721B B. Passwords(贪心)

    题目链接: B. Passwords time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  4. poj2387 Til the Cows Come Home 最短路径dijkstra算法

    Description Bessie is out in the field and wants to get back to the barn to get as much sleep as pos ...

  5. CSS设置滚动条样式

    因为在现在的大部分项目中很多都用到了滚动条,有时候用到模拟的滚动条,现在说下滚动条的CSS也能解决. 比如网易邮箱的滚动条样子很好看,就是利用的CSS来设置的,而且是webkit浏览器的.如图所示: ...

  6. Python中的逗号有什么作用?

    最近研究python  遇到个逗号的问题 一直没弄明白 今天总算搞清楚了 1.逗号在参数传递中的使用: 这种情况不多说  没有什么不解的地方 就是形参或者实参传递的时候参数之间的逗号 例如def  a ...

  7. 简单的抓取淘宝关键字信息、图片的Python爬虫|Python3中级玩家:淘宝天猫商品搜索爬虫自动化工具(第一篇)

    Python3中级玩家:淘宝天猫商品搜索爬虫自动化工具(第一篇) 淘宝改字段,Bugfix,查看https://github.com/hunterhug/taobaoscrapy.git 由于Gith ...

  8. HDU 4121 Xiangqi --模拟

    题意: 给一个象棋局势,问黑棋是否死棋了,黑棋只有一个将,红棋可能有2~7个棋,分别可能是车,马,炮以及帅. 解法: 开始写法是对每个棋子,都处理处他能吃的地方,赋为-1,然后判断将能不能走到非-1的 ...

  9. HDU 5033 Building --离线+单调栈

    题意:给一些建筑物,x表示横坐标,h表示高度,然后查询某些坐标x,问从该点看向天空的最大张角是多大. 解法:离线操作,读入所有数据,然后按x升序排序,对每一个查询的x,先从左到右,依次添加x坐标小于x ...

  10. 第23章 SEH结构化异常处理(2)_编译器对系统SEH机制的封装

    23.2 编译器层面对系统SEH机制的封装 23.2.1 扩展的EXCEPTION_REGISTRATION级相关结构:VC_EXCEPTION_REGISTRATION (1)VC_EXCEPTIO ...