表格存储数据模型和查询操作

摘要

       本篇文章主要会详细聊一下表格存储的查询操作,以及如何根据业务的需求来设计表结构以支持特定条件的查询。

       在理解查询操作之前,会简单描述一下表格存储的数据模型,以加深对查询操作的理解。

数据模型

表格存储(TableStore)的数据模型可以简化为使用下面这个数据结构来表示:

表格存储数据模型: SortedMap<PrimaryKey, List<Column>>

       逻辑上理解表格存储的数据模型,就是一个SortedMap,只不过这是一个非常巨大的SortedMap,可承载的数据量可达到上亿、上百亿甚至更多条,数据量上限完全可以随着集群的规模水平扩展。

       要支撑这么多数据的存储和查询,必须通过分布式的解决方案。逻辑上的数据模型,映射到实际的物理架构图如下:

数据模型的几个基础概念可以参考产品文档。

       在表格存储内部,一个表在创建的时候需要定义主键,主键会由多列组成,我们会选择主键的第一列作为分片键。当表的大小逐渐增大后,表会分裂,由原来的一个分区自动分裂成多个分区。触发分裂的因素会有很多,其中一个很关键的因素就是数据量。分裂后,每个分区会负责某个独立的分片键范围,每个分区管理的分片键范围都是无重合的,且范围是连续的。在后端会根据写入数据行的分片键的范围,来定位到是哪个分片。

查询操作

表格存储提供的查询API包括:

  • GetRow: 给定行的主键,查询某一行。
  • GetRange:给定行的主键范围,查询该范围内的所有行。
  • BatchGetRow:给定多行的主键,查询多行。

       从本质上来说,表格存储只提供两种类型的查询:单行查询和范围查询,BatchGetRow只是批量的单行查询。上面也提到了表格存储的数据模型其实是逻辑上的一个巨大的SortedMap,那查询操作也能完全映射到SortedMap提供的相应接口(以Java举例):

操作类型 SortedMap接口 接口说明
单行查询 V get(Object key)); Returns the value to which the specified key is mapped.
范围查询 SortedMap subMap(K fromKey, K toKey); Returns a view of the portion of this map whose keys range from fromKey, inclusive, to toKey, exclusive.

主键的比较

       主键由多列组成,大小比较的规则是:会按TableMeta定义的主键顺序,依次比较各个主键列,若当前比较的主键列值相等,则比较下一列;若当前比较的主键列不相等,则该主键列的大小决定主键的大小;当所有主键列都相等时,才代表主键相等。

不同类型的主键的比较规则:

类型 比较规则 代码
整型(Integer) 有符号长整型比较 Long.compareTo(Long other)
布尔型(Boolean) 布尔型比较 Boolean.compareTo(Boolean other)
字符串型(String) 字典序比较 String.compareTo(String other)
字节型(Binary) 字典序比较 可参考: UnsignedBytes.lexicographicalComparator

举个简单的例子,假设一个表有3列主键列,分别是:整型、字符串型和整型:

  • (10, 'abc', 10) == (10, 'abc', 10) 所有主键列均相等
  • (10, 'abc', 10) < (11, 'abc', 10) 第一列主键列比较出大小
  • (10, 'abc', 0) > (10, 'bbc', 10) 第一列主键列相等,第二列主键列比较出大小,即使第三列主键列也不同。

单行查询

       单行查询必须指定行的主键,根据上一章描述的比较规则,在表格存储内部查找到相同主键的行,并根据指定的查询条件,返回整行或者部分列。

范围查询

       范围查询必须指定两个主键,一个作为范围的起始(包含),一个作为范围的终止(不包含)。在表格存储内部,会根据上面章节提到的主键的比较规则,返回大于等于起始主键且小于终止主键的所有的行。

范围查询误区

这里必须注重提到的一点,很多用户对范围查询有一个误解,认为范围查询等于条件查询,举个例子:

假设表有三个主键: [PK1(INTEGER), PK2(STRING), PK3(INTEGER)]

给定的查询范围为:
    起始主键:[PK1 = 10, PK2 = 'h', PK3 = 5]
    终止主键:[PK1 = 15, PK2 = 'z', PK3 = 9]

很多用户会将这个查询条件误解为:
    10 <= PK1 < 15 and 'h' <= PK2 < 'z' and 5 <= PK3 < 9

而正确的理解应该是:
    起始主键 <= 行主键 < 终止主键

为更好的理解以上的误解,我们拿实际的数据来解释这个问题,假设一张表的数据如下:

行号 PK1 PK2 PK3
1 10 'a' 0
2 11 'a' 0
3 11 'b' 0
4 12 'a' 0
5 12 'c' 0
6 15 'z' 10
7 16 'a' 0
8 16 'a' 1

       如果理解为10 <= PK1 < 15 and 'h' <= PK2 < 'z' and 5 <= PK3 < 9这个查询条件,我们应该查不出任何数据出来,因为表中的数据没有一行是满足条件的。

但是实际的情况却是会返回行:2、3、4和5。

这是为什么呢?看下表就明白了。

行号 PK1 PK2 PK3
1 10 'a' 0
起始主键 10 'h' 5
2 11 'a' 0
3 11 'b' 0
4 12 'a' 0
5 12 'c' 0
终止主键 15 'z' 9
6 15 'z' 10
7 16 'a' 0
8 16 'a' 1

       在表格存储内部,会把范围查询给定的起始主键和终止主键根据比较规则定位到行,在这个例子中,起始主键处于第一行和第二行中间,而终止主键位于第五行和第六行中间。范围查询会返回这个范围内的所有行,而这个范围内的行就包括2、3、4和5行。

高级查询

       通过上一章的讲述,我们知道表格存储只提供单行查询和范围查询这两个简单的查询功能,也明白了范围查询不等于条件查询。而在很多业务场景下,简单的单行和范围查询并不能满足业务的需求。

       所以本章我会再讲述下表格存储如何支持一些复杂的查询场景。

条件过滤

       我们提供的范围查询不等于条件查询,但是在电商、社交等业务场景,在场景上需要的是条件查询。

       在我们提供条件过滤之前,一般的做法是先范围查询出所有可能满足条件的行,然后在业务服务端根据条件进行筛选。这种方法的坏处是,服务端会返回大量的无用数据,浪费了网络带宽。

       针对这个问题,表格存储推出了Relation Filter,支持在服务端对读出的数据做过滤,只将过滤后的结果返回给客户端。

       但是要注意的是,虽然范围查询加上条件过滤,客户端拿到的数据少了,但是服务端扫描的数据并没有少。这与传统关系型数据库有点不同,传统关系型数据库的条件查询可以用索引来优化,减少查询的数据量。由于表格存储没有提供索引,所以没法做这个优化。带来的缺点是,如果需要进行条件过滤的查询范围过大,则查询会非常慢,所以不建议通过条件过滤在一个很大的范围内查询数据,非常不高效以及不经济。

       条件过滤适用于一些比较灵活的查询场景,例如根据某些动态属性列的条件来做过滤,且过滤的范围都是比较小的业务场景。

多维度查询

       上面提到的条件过滤,能满足的场景也是受限的。例如如果查询的结果需要扫描整张表才能拿到,那显然这种做法就不可接受。

举个简单的例子,有一个业务场景,使用OTS存储『用户对文章的点赞』,表结构设计如下:

PK1 PK2 PK2
用户ID 时间戳 文章ID

通过这张表,可以支持以下几种查询方式:

  1. 查询某个用户所有的点赞的文章
  2. 查询某个用户最近一段时间的点赞的文章

       但是当我们有了一个新的需求,例如想要看某篇文章被哪些用户点过赞,基于这张表可以怎么实现呢?最土的方式就是,范围查询整张表,过滤出特定文章ID的所有行。这种方案有个非常大的问题,就是它必须扫全表,效率上是完全无法接受的。

针对此种场景,我们推荐的做法是,再建另外一张表,结构如下:

PK1 PK2 PK2
文章ID 时间戳 用户ID

通过这张表,就能满足以下几种查询方式:

  1. 查询某个文章的所有点赞的用户
  2. 查询某个文章最近一段时间的点赞的用户

以上是最简单的基于表格存储做多维度查询的一个解决方案,当然也有其局限性:

  • 查询方式必须预定义,根据查询条件来决定构建哪几张表,查询模式无法灵活变动
  • 一笔数据需要同时写入多张表,多张表之间的数据一致性需要应用自己保证,所以只适用于接受最终一致或者允许不一致的业务场景

       支持多维度查询,还可通过组合使用表格存储和其它服务来解决,例如表格存储加ElasticSearch,通过表格存储来保存数据主题,ElasticSearch来做索引。这又是另外一个话题了,不在这里赘述,感兴趣的可以留言交流。

总结

表格存储的数据模型非常简单,理解透之后,也就可以非常简单的理解表格存储当前提供的几种查询方式。

表结构设计是相对灵活的,需要根据不同的业务场景来设计,设计时需要考虑查询的效率。

表格存储无法支撑所有的查询场景,在使用时必须有一些取舍。

有任何表结构设计的咨询需求,欢迎一起交流!

时间: 2024-09-17 23:10:43

表格存储数据模型和查询操作的相关文章

表格存储技术方案实践及客户案例分享

表格存储是一款2014年10月份正式商业化的NoSQL数据存储服务,在商业化之前,早在2010年就在阿里云内部开始使用,云邮箱和云OS都是表格存储最早的一批用户.到目前,无论是在阿里集团内部还是在公共云环境上,在移动社交.金融风控.电商物流.存储备份.物联网IoT.日志监控.大数据分析报表等领域都有着广泛的用户基础与成熟的实践方案. 为了方便更多的用户了解和使用表格存储,该帖子会将最近非常有参考意义的方案设计.技术实践及相关客户分享的博客文章汇总到这里,大家可以在这里快速查找到和自己业务场景相近

从SQL到NoSQL—如何使用表格存储

SQL 还是 NoSQL? NoSQL 是一个用于描述高扩展高性能的非关系数据库的术语. NoSQL 数据库提供的 schemafree 数据模型能够让应用无需预先定义表结构,适应业务的多元化发展,而对超大数据规模和高并发的支持让 NoSQL 数据库得到了广泛的应用. 访问数据库 创建表 写入数据 检索数据 更新数据 删除数据 删除表 SQL 与 NoSQL 数据库对比 关系型数据库 NoSQL 数据库 数据模型 关系模型对数据进行了规范化,严格的定义了表.列.索引.表之间的关系及其他数据库元素

深入对比 HBase 与阿里云的表格存储服务

随着互联网时代的兴起,NoSQL 类型数据库正日渐成为大数据时代下分布式数据库领域的主力,分布式 NoSQL 数据库中最为著名的莫过于 HBase.谷歌的 Bigtable 于 2016 年推出了兼容 HBase 的接口,而作为国内最早推出分布式 NoSQL 数据存储服务的阿里云表格存储也在最近正式发布了 TableStore HBase Client,能够帮助用户将业务轻松从 HBase 迁移至表格存储. 让我们来深入对比下阿里云的表格存储与 HBase 到底有何异同. 软件与服务 通过对表格

一分钟了解阿里云产品:表格存储

一.             概述   阿里云产品种类繁多,今天让我们一起来瞧瞧表格存储(Table Store)吧.   什么是表格存储呢?   简单来说,表格存储是构建在阿里云飞天分布式系统之上的NoSQL数据存储服务,提供海量结构化数据的存储和实时访问.表格存储以实例和表的形式组织数据,通过数据分片和负载均衡技术,实现规模上的无缝扩展.应用通过调用表格存储 API / SDK 或者操作管理控制台来使用表格存储服务.     那么,表格存储有什么优势呢?   表格存储具有很好的扩展性.应用在

表格存储新手指南:如何实现分页查询

本篇文章会介绍如何在表格存储上实现分页查询. 有别于传统关系型数据库支持的翻页查询,在NoSQL的数据模型和API上,实现分页功能会有以下的限制,需要特别注意: 不支持获取整个范围的行数,即无法计算总的页数. 不建议使用设置offset来跳页,因为offset的过滤是在客户端做,服务端不管如何,都会扫描读出那么多的数据.若offset设定过大,则可能导致本次查询时间过长. 最佳实践是只提供顺序翻页的功能,一页一页顺序往下翻. 下面是一个实现分页读接口的示例代码,提供offset过滤以及读取指定页

表格存储如何实现高可靠和高可用

系列文章 表格存储如何实现高可靠和高可用表格存储如何实现跨区域的容灾 前言 本文会介绍一款分布式NoSQL如何实现数据高可靠和服务高可用,这是一款云上的NoSQL服务,叫做表格存储.对于分布式NoSQL,大家可能会想到很多名字,比如HBase.Cassandra,AWS的DynamoDB等,这类NoSQL在设计之初就作为一个分布式系统支持超大规模的数据量与并发.此外大家可能还会想到MongoDB和Redis,这两个也提供集群功能,但是一般需要人为的配置sharding和复制集/主从等. 表格存储

表格存储在互联网风控和金融数据服务上的应用实践

引言 当前,第三方支付.P2P网贷.宝宝类理财.众筹等金融产品层出不穷,随着金融知识的普及,全民参与又进一步促进了互联网的发展.海量交易数据,实时在线访问,业务快速的迭代变化都对传统金融解决方案提出了更高的要求,而互联网金融本身的开放性,低门槛,征信信息的缺乏,又容易发生各类风险问题,这有给传统金融解决方案带来的新的挑战.借助云计算.大数据.搜索引擎等新一代高新技术,给互联网金融带来了新的机会. 新兴的互联网金融数据主要有以下几个特点: 海量数据 由于参与的人数众多且活跃度较高,日交易单数通常能

表格存储服务在社交应用场景的实践

阿里云的表格存储服务(http://www.aliyun.com/product/ots)是一款面向PB级结构化/半结构化数据存储和百万级高并发读写访问的NoSQL数据库服务,在移动社交场景中有着非常广发的应用,如今非常火热的钉钉也将后台的消息推送和存储功能从MySQL迁移到表格存储上,以获得更加优秀的高并发和规模扩展能力:同时也有非常多的创业企业将企业自身针对客户的消息推送能力基于表格存储来构建.本文将详细介绍表格存储在移动社交中的技术实践.本文的主要内容已经在2016年云栖大会深圳场的存储论

表格存储结合Elasticsearch进行搜索的场景分析和实践

表格存储结合Elasticsearch进行搜索的场景分析和实践 表格存储(TableStore)是什么 TableStore是一个构建在阿里云飞天分布式系统上的Nosql数据库服务,熟悉阿里云的同学肯定听说过飞天5K,飞天是一个可以管理5000台机器的分布式系统,TableStore作为构建在其上的一个Nosql数据库,可以承载海量(单表几百TB)的数据存储,同时数据有三份拷贝,数据安全性有极高的保证. TableStore的数据是以行进行组织的,每行包含多个主键列和多个属性列,主键列的列名和类