SequoiaDB 系列之三 :SequoiaDB的高级功能
上一篇简单描述了一下SequoiaDB的简单CRUD操作,本篇将讲述一下稍微高级点的功能。
部署在我机器上的集群环境,在经过创建名字为"foo"的cs,创建名字为"bar"的cl,以及插入一些数据之后,并没有删除掉,因此在本篇中会继续使用。
首先,我们先看看,在SequoiaDB的安装目录中的database目录里面,有那些文件:
~$ ls /opt/sequoiadb/database/data/11850
我们会发现有几个文件:foo.1.idx,foo.1.data
正好是我们创建的cs的名字。是不是巧合呢?
验证一下,依次做以下操作:
- 启动两个终端:终端1,终端2;
- 在终端1中,进入SequoiaDB的shell执行环境;
- 连接上数据库。
以上我不再写出操作,读者可以自己操作一下,有利于熟悉常用操作。
先删除Collection Space,执行:
> db.dropCS("foo")
然后在终端2下,查看一下文件:
~$ ls /opt/sequoiadb/database/data/11850
这个时候,我们发现foo.1.data和foo.1.idx文件没有了。
再回到终端1,重新创建名为“foo”的cs:db.createCS("foo")
切换到终端2,再次查看文件:
~$ ls /opt/sequoiadb/database/data/11850
这个时候,foo.1.data 和 foo.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的高级功能的更多相关文章
- SequoiaDB 系列源码分析调整
犹豫我经验尚不够丰富,有大牛跟我说,以我这样定下的结构来分析源码,学习效果不太好. 应该先从程序的进程入口函数开始,慢慢的跟流程来分析.先通过系统的启动.退出来分析所用到的技术,像进程模型,线程模型等 ...
- SequoiaDB 系列之四 :架构简析
在本系列的第一篇中,简述了SequoiaDB的安装,以及一个(伪)集群的部署 第二篇和第三篇对SequoiaDB的集群,做了简单地操作. 在本篇中,将对SequoiaDB的架构进行简单的分析. 因为自 ...
- SequoiaDB 系列之六 :源码分析之coord节点
好久不见. 在上一篇SequoiaDB 系列之五 :源码分析之main函数,有讲述进程开始运行时,会根据自身的角色,来初始化不同的CB(控制块,control block). 在之前的一篇Sequ ...
- SequoiaDB 系列之五 :源码分析之main函数
好久好久没有写博客了,因为一直要做各种事,工作上的,生活上的,这一下就是半年. 时光如梭. 这两天回头看了看写的博客,感觉都是贻笑大方. 但是还是想坚持把SequoiaDB系列写完. 初步的打算已经确 ...
- SequoiaDB 系列之二 :SequoiaDB的简单CRUD操作
上一篇通过一系列的操作,终于把SequoiaDB的集群部署到单台机器上了. 建议去安装体验一下吧. 在整个环境的部署的体验来看,并没有MongoDB的部署简单,但是比MongoDB的部署要清晰.Mon ...
- SequoiaDB 系列之七 :源码分析之catalog节点
这一篇紧接着上一篇SequoiaDB 系列之六 :源码分析之coord节点来讲 在上一篇中,分析了coord转发数据包到catalog节点(也有可能是data节点,视情况而定).这一次,我们继续分析上 ...
- SLAM+语音机器人DIY系列:(二)ROS入门——10.在实际机器人上运行ROS高级功能预览
摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...
- Elasticsearch系列---几个高级功能
概要 本篇主要介绍一下搜索模板.映射模板.高亮搜索和地理位置的简单玩法. 标准搜索模板 搜索模板search tempalte高级功能之一,可以将我们的一些搜索进行模板化,使用现有模板时传入指定的参数 ...
- Sql Server来龙去脉系列之三 查询过程跟踪
我们在读写数据库文件时,当文件被读.写或者出现错误时,这些过程活动都会触发一些运行时事件.从一个用户角度来看,有些时候会关注这些事件,特别是我们调试.审核.服务维护.例如,当数据库错误出现.列数据被更 ...
随机推荐
- nginx根据IP限制访问
nginx有两个模块可以控制访问 HttpLimitZoneModule 限制同时并发访问的数量 HttpLimitReqModule 限制访问数据,每秒内最多几个请求 http{ ## ...
- 一个不错的shell 脚本教程 入门级
一个很不错的bash脚本编写教程,至少没接触过BASH的也能看懂 建立一个脚本 Linux中有好多中不同的shell,但是通常我们使用bash (bourne again shell) 进行s ...
- Google 以图搜图 - 相似图片搜索原理 - Java实现
前阵子在阮一峰的博客上看到了这篇<相似图片搜索原理>博客,就有一种冲动要将这些原理实现出来了. Google "相似图片搜索":你可以用一张图片,搜索互联网上所有与它相 ...
- Linux nmap
一.简介 Nmap(Network Mapper)是一款开放源代码的网络探测和安全审核工具.它用于快速扫描一个网络和一台主机开放的端口,还能使用TCP/IP协议栈特征探测远程主机的操作系统类型.nma ...
- linux文件压缩与打包
在linux中常见的压缩命令 首先,在linux中压缩文件的扩展名大多是 *.gz gzip程序压缩的文件 *.bz2 bzip2程序压缩的文件 *.tar tar程序打包的数据,并没有压缩过 *.t ...
- Android 开发框架
Android 开发框架包括基本的应用功能开发.数据存储.网络访问三大块. 1 应用方面 一般而言,一个标准的Android 程序包括Activity.Broadcast Intent Receive ...
- 嵌入式开发板iTOP4412学习开发板
网站:http://www.topeetboard.com 淘宝:https://item.taobao.com/item.htm?_u=okcahs0f42a&id=38712193806 ...
- Android+Sqlite 实现古诗阅读应用(一)
不说网络app,很多本地的app都有一些随机的内容推送,比如随机推送一些小知识,古诗,名言名画什么的,界面制作的好看一点就能看起来特别的文艺范, 最近就是看了这样的一些应用,就想自己实现一下,这种方法 ...
- A + B Problem II
之前总是在查阅别人的文档,看着其他人的博客,自己心里总有一份冲动,想记录一下自己学习的经历.学习算法有一段时间了,于是想从算法开始自己的博客生涯O(∩_∩)O~~ 今天在网上看了一道大数相加(高精度) ...
- 《至少有那天》——IU
//<你的意义>中文版 那天冷的让人好想哭 可是我那一天看到了爱情 湖边的薄冰和老树 就在零下七度那一天 你和我牵手 慢慢聊着以前那些童话 可能它们都有些意义吧 是吗 一个吻 一滴眼泪 一 ...