关于SQL/NoSQL数据库搜索/查询的思考

转载请注明出处:jiq?钦‘s technical Blog

Hbase特征:

最近在学习Hbase,Hbase基于行健是建立了索引的,查询速度会非常快,完全实时。

但是Hbase要基于行健之外的字段进行查询,那么就只能是全盘扫描,基本上不可接受。

所以Hbase一般来说会针对具体的应用场景来设计行健,利用基于行健的查询的实时性来达到Hbase数据的实时查询。

关系型数据库基于索引字段的实时查询:

然后联想到关系型SQL数据库,他们针对主键是建立了B/B+/B-树索引的,基于主键的查询是实时的,范围扫描也是实时的。

更重要的是,基于非主键的其他字段,关系型数据库也可以很方便地为其建立索引,从而达到实时查询。

Hbase的二级索引:

那么Hbase这种NOSQL数据库可不可以也为除了行健之外的字段建立索引,从而针对这些字段的查询达到实时的效果呢?

答案是肯定的。

在Hbase里面针对除了行健之外的字段建立索引称之为“二级索引”。

通常建立二级索引的方式是利用Hbase中的“协处理器”,协处理器主要包含Observer和Endpoint两种模式,前者类似于关系型数据库中的触发器trigger,而后者类似于关系型数据库中的存储过程,通过Observer可以讲用户代码嵌入到现有的运行过程中,在特定的时间发生时就会触发对应的这段用户代码,即回调函数。目前有三种Observer接口:

1、  RegionObserver:提供对应数据操作事件的钩子,该类操作有Get、Put、Delete、Scan 等等。每一个 region 都会有一个 RegionObserver 实例。

2、  WALObserver:提供预写日志(write-ahead log,WAL)相关操作的钩子。WALObserver在WAL处理过程中运行,每一个region server有一个实例。

3、  MasterObserver:提供DDL操作的钩子,该类操作有创建表、删除表、修改表的元信息等。MasterObserver运行在HBase master上。

每一类observer都可以加载多个,所有的observer会按链式顺序执行。

Hbase社区关于使用Coprocessor框架建立二级索引的方案主要有三种:

1、             基于WALObserver在一个索引表内生成索引,通过栏截Write Ahead Log写入操作,提取写入HLog的KeyValue对信息,把相应信息存储到索引表中。

2、             基于RegionObserver在一个Region内维护一个索引列族,通过拦截Region的put、delete等操作,提取相应信息存储到同一个Region的索引列族中,这种方式的索引是局部索引,不支持全排序。

3、             基于RegionObserver在一个索引表内生成索引,通过栏截Region的put、delete等操作,提取相应信息存储到索引表中。

这个时候大家可能想知道索引表是什么样子的,一般来说,如果某一个Hbase表中有一列叫做所在地区,存储的是用户当前所在的城市,比如南京,上海这样,那么要针对着一些创建对应的二级索引,当插入新的一行记录的时候,在协处理器的钩子函数Observer中就会提取出这一列的值,在对应的索引表中插入一行索引记录,这行索引记录的rowkey是该列提取出来的值,而将这行索引记录的rowkey是刚才插入的那条记录的真正的rowkey,这样在检索地区,比如用户输入一个“南京”,或者执行基于Hbase的SQL语句:select
* from userTable where location=’南京’的时候,就会检测到location这一列已经被创建了二级索引,所以就会在索引表中查找rowkey为’南京’的记录,然后取出真正的rowkey,在对应的数据表中取出对应的记录,展示给用户。

关系型SQL数据库和NoSQL数据的针对非主键的索引建立还是有很多相似的地方的。

二级索引与全文检索:

但是有一点要注意,二级索引和全文检索是两个不同的概念:

建立二级索引一般是为了能够实时查询,而全文检索的目的是为了能够快速地在数据库中查找到自己关心的内容。前者是属于一种针对某一列值进行完全匹配的方式,而后一种是需要对数据进行分词,对分词的结果建立‘倒排索引’,从而能够支持根据特定的关键字查找其所属的那段内容(或者说所属的文档/记录)。

Hbase中的全文检索:

那么在Hbase中的全文检索一般怎么做呢?

之前接触过solr,是在Lucence上面的一层封装好的库,支持搭建分布式集群方式的全文检索服务。其原理就是简单地将要进行全文检索的字段的内容进行分词,然后将分词后的结果分别建立倒排索引。

Hbase中要实现全文检索,一般就可以结合Lucence/Solr来做,利用他们的自动创建索引的功能,针对Solr来说,无非就是其输入源不同了,以前可能一般针对关系型数据库,现在输入源变为了Hbase。

全文检索不是实时的,并不是说你往Hbase中插入一条记录,马上你就可以实时地在较快的时间内查询到,因为后台建立索引是需要一个过程的,一般来说可能几分钟左右吧。

关系型数据库中的全文检索:

在这里了解到了Hbase的全文检索之后,自然而然就联想到了关系型数据库中的全文检索。

关系型数据库的全文检索和Hbase的其实几乎是一样的。

比较流行的方式也是采用和Solr这样成熟的开源的全文检索库结合实现,将关系型数据库作为Solr的数据输入源,它们会定期自动从关系型数据库中抽取数据,或者由关系型数据库的插入/删除/更新操作触发,来在Solr中为指定的字段分词后的结果建立倒排索引。

另外国内也有一些比较出名的商用的全文检索引擎,我们公司目前使用的就是这种。

关系型数据库中的模糊查询like:

在思考查询的时候,很难不想到关系型数据库中的模糊查询。

个人觉得,模糊查询看似是和针对某一字段的全文检索类似,其实在功能上讲(不谈效率)要比这个更加强大,比如你针对“我是季义钦”这句话,你可能利用全文检索引擎,分词时候会分成“我”,“是”,“季义钦”三个词(实际的分词器可能不这样,我只是举个例子),这个时候你全文检索只能够搜索到“我”,“是”,“季义钦”三个词,如果你要搜索“义钦”那么就会搜索不到。

但是关系型数据库中的模糊查询,你要是用“%义钦”来查询绝对能查询到。

为什么呢?

我了解了一下,发现关系型数据库中的模糊查询并没有为这个要模糊查询的字段建立整个字段的索引,更没有分词之后再针对分词结果建立索引,而是拿到“%义钦”的查询条件之后,全表扫描,对这个正则表达式进行匹配。

虽然你把通配符放在前面,像“like %义钦”这样,这个查询肯定不会走索引,而是会全表扫描,但是如果你的模糊查询是“like 季%”,即将通配符放在前后面,那么这个查询是有可能走索引的,而且通配符放在前面的查询其实是有一些技巧来进行具体的优化的,比如看看这个例子:http://blog.csdn.net/firstboy0513/article/details/6912632

在大部分关系型数据库中,其实是可以为指定字段建立全文索引(注意,这里所说的并不是不是采用第三方全文检索引擎)的,比如MYSQL中像这样:

MATCH (col1,col2,...) AGAINST (expr[search_modifier])

search_modifier: { IN BOOLEAN MODE | WITHQUERY EXPANSION }

例如:SELECT * FROM tab_name WHERE MATCH (col1,col2) AGAINST(search_word);

这里的table需要是MyISAM类型的表,col1、col2需要是char、varchar或text类型,在查询之前需要在col1和col2上建立一个全文索引。

下面有一段话需要注意:

MySQL在高并发连接、数据库记录数较多的情况下,SELECT... WHERE ... LIKE ‘%...%‘的全文搜索方式不仅效率差,而且以通配符%和_开头作查询时,使用不到索引,需要全表扫描,对数据库的压力也很大。MySQL针对这一问题提供了一种全文索引解决方案,这不仅仅提高了性能和效率(因为MySQL对这些字段做了索引来优化搜索),而且实现了更高质量的搜索。但是,至今为止,MySQL对中文全文索引无法正确支持。

--- 这个问题可以通过使用一些MYSQL中文全文检索插件来解决。

关于Oracle中的全文检索可以参考这篇文章:http://www.iteye.com/topic/1118055

本文属于个人见解,如有疑问或者指正,欢迎讨论,谢谢!

关于SQL/NoSQL数据库搜索/查询的思考

时间: 2024-11-08 03:54:48

关于SQL/NoSQL数据库搜索/查询的思考的相关文章

大约SQL/NoSQL数据库搜索/思考查询

转载请注明出处:jiq?钦's technical Blog Hbase特征: 近期在学习Hbase.Hbase基于行健是建立了索引的,查询速度会很快,全然实时. 可是Hbase要基于行健之外的字段进行查询.那么就仅仅能是全盘扫描,基本上不可接受. 所以Hbase一般来说会针对详细的应用场景来设计行健,利用基于行健的查询的实时性来达到Hbase数据的实时查询. 关系型数据库基于索引字段的实时查询: 然后联想到关系型SQL数据库,他们针对主键是建立了B/B+/B-树索引的,基于主键的查询是实时的.

sql server数据库数据查询成功

1 <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> 2 <%@ page import="java.sql.*" %> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" &q

NoSQL数据库介绍(3)

3 基本概念,技术和模式 本章概述了一些NoSQL数据存储常见的基本概念.技术与模式,并不仅限于一类非关系型数据库或一个单一的NoSQL存储.众多NoSQL数据存储和个别产品的具体概念和技术将在随后的章节中讨论. 3.1 一致性 3.1.1 CAP理论 在2000年的ACM PODC研讨会上主题为"走向鲁棒的分布式系统"的演示文稿中,Eric Brewer提出了所谓的CAP理论([ Bre00 ]),它目前在大型网络公司(如Amazon,参见[ Vog07 ].[ Vog08 ])以及

50种方法优化SQL Server数据库查询(转载)

原文地址:http://www.cnblogs.com/zhycyq/articles/2636748.html 查询速度慢的原因很多,常见如下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列导致查询不优化. 4.内存不足 5.网络速度慢 6.查询出的数据量过大(可以采用多次查询,其他的方法降低数据量) 7.锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷) 8.sp_lock,sp_who,活动的用

NoSQL 数据库概览及其与 SQL 语法的比较

NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用的难题. 本文对NoSQL数据库的定义.分类.特征.当前比较流行的NoSQL数据库系统等进行了简单的介绍,并对NoSQL和SQL语法进行了简单的比较,为大家对NoSQL数据库的学习提供了有益的参考. 一.NoSQL的出现 关系型数据库系统多年来在解决数据存储.服务和处理问题方面取得了巨大的成功.一些大型的公司使用关系型数据库建立了自己的系统,如联机事务处理系统和后端分析应用系统.联机事务处理(OLTP)系统用

SQL Server 全文搜索 配置、查询初体验

一.使用SQL Server全文搜索配置 要使用SQL Server的全文搜索服务,需要进行如下配置. 1.开启全文搜索服务: 2.开启数据库的全文索引功能: --开启数据库的全文搜索功能 EXEC sp_fulltext_database 'enable'; 3.创建全文索引目录: --创建全文索引目录 CREATE FULLTEXT CATALOG IndexCatalog ON FILEGROUP [PRIMARY] IN PATH 'E:\SQLServerIndex' AS DEFAU

优化SQL Server数据库查询方法

SQL Server数据库查询速度慢的原因有很多,常见的有以下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列导致查询不优化. 4.内存不足 5.网络速度慢 6.查询出的数据量过大(可以采用多次查询,其他的方法降低数据量) 7.锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷) 8.sp_lock,sp_who,活动的用户查看,原因是读写竞争资源. 9.返回了不必要的行和列 10.查询语句不好,没有优

SQL Server数据库查询速度慢的原因和解决方法

问 SQL Server数据库查询速度慢的原因有很多,常见的有以下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列导致查询不优化. 4.内存不足 5.网络速度慢 6.查询出的数据量过大(可以采用多次查询,其他的方法降低数据量) 7.锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷) 8.sp_lock,sp_who,活动的用户查看,原因是读写竞争资源. 9.返回了不必要的行和列 10.查询语句不好,没

转载 50种方法优化SQL Server数据库查询

原文地址 http://www.cnblogs.com/zhycyq/articles/2636748.html 50种方法优化SQL Server数据库查询 查询速度慢的原因很多,常见如下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列导致查询不优化. 4.内存不足 5.网络速度慢 6.查询出的数据量过大(可以采用多次查询,其他的方法降低数据量) 7.锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷