关系型、非关系型数据库存储选型盘点大全( 三 )


全文搜索的原理是倒排索引 , 我们看一下什么是倒排索引 , 它是关键字–>文档的映射 , 举例来说 , 现在这里有四个短句:"TomisTom""Tomismyfriend""Thankyou,Betty""TomisBetty'shusband"
搜索引擎会根据一定的分词规则将一句话切成多个关键字 , 并以关键字的维度维护关键字在每个文本中的出现次数 。 这样下次搜索“Tom”关键字的时候 , 由于Tom这个词语在“TomisTom”、“Tomismyfriend”、“TomisBetty’shusband”三句话中都出现过 , 因此这三条记录都会被检索出来 , 而且由于”TomisTom”这句话中”Tom”出现了2次 , 因此这条记录对”Tom”这个单词的匹配度最高 , 最先展示 。 这就是搜索引擎倒排索引的基本原理 , 假设某个关键字在某个文档中出现 , 那么倒排索引中有两部分内容:文档ID该关键字在该文档中出现的位置情况
相对应的 , 我们搜索”BettyTom”这两个词语也是一样 , 搜索引擎将”BettyTom”切分为”Tom”、”Betty”两个单词 , 根据开发者指定的满足率 , 比如满足率=50% , 那么只要记录中出现了两个单词之一的记录都会被检索出来 , 再按照匹配度进行展示 。
搜索型NoSql以ElasticSearch为例 , 它的优点为:
1)支持分词场景、全文搜索 , 这是区别于关系型数据库最大特点 。
2)数据写文件无丢失风险 , 在集群环境下可以方便横向扩展 , 可承载PB级别的数据 。
3)支持条件查询 , 支持聚合操作 , 类似关系型数据库的GroupBy , 但是功能更加强大 , 适合做数据分析 。
4)高可用 , 自动发现新的或者失败的节点 , 重组和重新平衡数据 , 确保数据是安全和可访问的 。
同样 , ElasticSearch也有比较明显的缺点:
1)性能全靠内存来顶 , 也是使用的时候最需要注意的点 , 非常吃内存 , 大数据量下64G+SSD基本就是标配 , 相同的配置多一倍内存 , 一个月差不多就要多花好多钱 。 至于ElasticSearch内存主要用在以下几个地方:IndexingBuffer----ElasticSearch基于Luence , Lucene的倒排索引是先在内存里生成 , 然后定期以SegmentFile的方式刷磁盘的 , 每个SegmentFile实际就是一个完整的倒排索引 。 各类缓存----FilterCache、FieldCache、IndexingCache等 , 用于提升查询分析性能 , 例如FilterCache用于缓存使用过的Filter的结果集 。 SegmentMemory----倒排索引前面说过是基于关键字的 , Lucene在4.0后会将所有关键字以FST这种数据结构的方式将所有关键字在启动的时候全量加载到内存 , 加快查询速度 , 官方建议至少留系统一半内存给Lucene 。 CluterStateBuffer----ElasticSearch被设计为每个Node都可以响应用户请求 , 因此每个Node的内存中都包含有一份集群状态的拷贝 , 一个规模很大的集群这个状态信息可能会非常大 。
2)数据结构灵活性不高 , 字段一旦建立就没法修改类型了 , 假如建立的数据表某个字段没有加全文索引 , 想加上 , 那么只能把整个表删了再重建 。
3)读写之间有延迟 , 写入的数据差不多1s样子会被读取到(数据写入时需要维护很多索引) 。
因此 , 搜索型NoSql最适用的场景就是有条件搜索尤其是全文搜索的场景 , 作为关系型数据库的一种替代方案 , 通常搜索型NoSql也会作为一层前置缓存 , 来对关系型数据库进行保护 。
此外 , 搜索型数据库还有一种非常重要的应用场景 。 我们可以想 , 一旦对数据库做了分库分表后 , 原来可以在单表中做的聚合操作、统计操作是否统统失效?例如我把订单表分16个库 , 1024张表 , 那么订单数据就散落在1024张表中 , 我想要统计昨天浙江省单笔成交金额最高的订单是哪笔如何做?这就是搜索型NoSql的另一大作用了 , 我们可以把分表之后的数据统一打在搜索型NoSql中 , 利用搜索型NoSql的搜索与聚合能力完成对全量数据的查询 。