首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何设计redis的数据结构,以执行类似于Redis中的DB查询?

如何设计redis的数据结构,以执行类似于Redis中的DB查询?
EN

Stack Overflow用户
提问于 2016-05-16 17:49:01
回答 3查看 9.8K关注 0票数 6

我有像Job,JobInfo这样的表格。我想像下面这样执行查询-

从作业J、JobInfo B中选择J.JobID,其中B.JobID = J.JobID和BatchID=5850以及B.Status=0和J.JobType<>2

我该如何编写我的redis数据类型,以便在redis中映射这样的查询?

如果我尝试将表作业的行映射到redis散列中,例如(散列jjobid1,状态2) &类似地,表JobInfo的行将再次映射为(散列jinfo jobid1,作业类型3)。

所以我的表可以是一组散列。可以使用条目来设置作业表JobSet:jobid &可以使用JobInfoSet:jobid这样的条目来设置JobInfo表

但是我不知道什么时候我会在JobSet & JobInfoSet上做一个烧结者。我该如何查询散列来获取密钥呢?因为集合jobSet的散列内容与表JobInfoSet的散列内容不同(它们可能具有不同的键值对。

那么,我到底会得到什么作为烧结器的输出呢?如何以键-值对的形式查询输出?

因此,这些表将是redis散列的集合

EN

回答 3

Stack Overflow用户

发布于 2016-08-12 17:31:10

Redis不是为以SQL方式构建数据而设计的。除了内存中的键值存储之外,它还支持五种类型的数据结构:字符串、散列、列表、集合和排序集合。从高层次上讲,这充分表明Redis旨在解决由于关系数据模型中的高计算量而产生的性能问题。但是,如果希望在内存结构中执行sql查询,则可能需要查看memsql

票数 2
EN

Stack Overflow用户

发布于 2016-12-03 17:08:46

其他答案对于版本3.4到redis来说是完全正确的

redis的最新版本,从4.0开始,包括对模块的支持。

模块的功能非常强大,碰巧我刚刚编写了一个小模块来将SQLite嵌入到redis本身;rediSQL

有了这个模块,你就可以在redis实例中使用一个功能齐全的SQL数据库了。

票数 2
EN

Stack Overflow用户

发布于 2016-11-09 05:55:51

让我们将SQL语句分解成不同的组件,我将尝试展示redis如何完成各个部分。

从作业J中选择J.JobID,J.JobName;

我们将"Job“中的每一行转换为redis中的散列,使用SQL主索引作为redis中的redis自然索引。例如: SQL

代码语言:javascript
复制
==JobId==|==Name==
123        Fred

Redis HSET Job:123名字Fred,可以概念化为

代码语言:javascript
复制
Job-123 => {"Name":"Fred"}

因此,我们可以将列作为散列字段存储在redis中

假设我们对JobInfo做了同样的事情。每个JobInfo对象都有自己的ID

代码语言:javascript
复制
JobInfo-876 => {"meta1": "some value", "meta2": "bla", "JobID": "123"}

在sql中,我们通常会在JobInfo.JobID上建立二级索引,但在NoSql中,我们维护自己的二级索引。

排序集在这方面很有用。因此,当我们想要通过某个字段来获取JobInfo对象时,在本例中是JobId,我们可以将它添加到一个排序的集合中,比如ZADD JobInfo-JobID123 JobInfo-876

这会产生一个包含1个元素的集合{JobInfo-876},得分为123。我意识到强制所有的JobID进入浮点分数范围不是一个好主意,但在这里和我一起工作吧。

现在,当我们想要查找给定JobInfo的所有JobID对象时,我们只需对索引进行对数(N)查找。ZRANGEBYSCORE JobInfo-JobID 123 123返回"JobInfo-876“

现在,为了实现简单的连接,我们只需通过按作业to存储作业键来重用这个JobInfo-JobID索引。ZADD JobInfo-JobID 123作业-123

因此,当执行类似于从作业中选择J.JobID、J.Name、B.meta1、JobInfo时,使用(JobID)。

这将转化为扫描JobInfo-JobID二级索引并重新组织返回的Job和JobInfo对象。ZRANGEBYSCORE作业信息-作业inf -inf +inf WITHSCORES 5 -> (作业-123,作业信息-876)

这些对象都共享相同的JobID。在CLient端,您将异步获取所需的字段。或者,您可以将这些查找嵌入到lua脚本中。这个lua脚本会让redis挂起很长一段时间。通常,redis试图对客户公平对待,并且更喜欢使用短的批处理查询,而不是一个长查询。

现在我们遇到了一个大问题,如果我们想要组合二级索引怎么办。假设我们在JobInfo.Status上有一个二级索引,在Job.JobType上有一个二级索引。如果我们创建一组具有正确JobType的所有作业,并将其用作JobInfo-JobID共享二级索引的筛选器,那么我们不仅会删除错误的Job元素,还会删除每个JobInfo元素。我猜我们可以获取交叉点上的分数(JobID),并使用这些分数重新获取所有JobInfo对象,但我们失去了一些过滤功能。

正是在这一点上,redis崩溃了。

这里有一篇来自redis创建者本人的关于二级索引的文章:http://redis.io/topics/indexes,他触及了多维索引的过滤目的。如您所见,他以一种非常通用的方式设计了数据结构。最吸引人的一点是,具有相同分数的排序集合元素是按字典序顺序存储的。因此,您可以很容易地让所有元素的得分为0,并利用Redis的速度,更像cockroachDB一样使用它,它依赖于全局顺序来实现许多SQL特性。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37251030

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档