Redis作为表的哈希用法

问题描述 投票:1回答:1

我想使用像Nosql数据库一样的redis,我有一些想法,就像下面。

假设我有3张表

1 - user
2 - post
3 - comment

我为每个表创建了如下的哈希值

hset user _usr_100 {"id":"_usr_100","name":"john","username"="jhn","age":25}
hset user _usr_101 {"id":"_usr_101","name":"adam","username"="adm","age":26}
hset user _usr_102 {"id":"_usr_102","name":"eric","username"="erc","age":27}

hset post _post_100 {"id":"_post_100","title":"title","content":"testpost","userid"="_usr_100"}
hset post _post_101 {"id":"_post_101","title":"title","content":"testpost","userid"="_usr_101"}
hset post _post_102 {"id":"_post_102","title":"title","content":"testpost","userid"="_usr_102"}

hset comment _comment_100 {"id":"_comment_100","content":"testpost","userid"="_usr_100","postid":"_post_100"}    
hset comment _comment_101 {"id":"_comment_101","content":"testpost","userid"="_usr_101","postid":"_post_101"}    
hset comment _comment_102 {"id":"_comment_102","content":"testpost","userid"="_usr_102","postid":"_post_102"}

当我想从redis中获取user(_user_100)时。

hget user _usr_100
{"id":"_usr_100","name":"john","username"="jhn","age":25}

当我想获得用户

hgetall user
{"id":"_usr_100","name":"john","username"="jhn","age":25}
{"id":"_usr_101","name":"adam","username"="adm","age":26}
{"id":"_usr_102","name":"eric","username"="erc","age":27}

在将json字符串逐个反序列化并填入列表中后,我有一个列表,这样我就可以进行一些操作(搜索,分组,顺序,分页......),我也可以对另一个哈希值(帖子,评论)做同样的事情。

我可以用它来删除、更新用户。

hdel user _usr_101 // deleted _usr_101
hset user _usr_100 {"id":"_usr_100","name":"john","username"="jhn","age":26} //updated age
hset user _usr_103 {"id":"_usr_103","name":"max","username"="max","age":15} //new user

hgetall user
{"id":"_usr_100","name":"john","username"="jhn","age":26}
{"id":"_usr_102","name":"eric","username"="erc","age":27}
{"id":"_usr_103","name":"max","username"="max","age":15}

这种用法的缺点是什么呢?你能不能提出另一个关于哈希的想法,把redis像nosql表一样使用。

hash redis
1个回答
1
投票

根据你的业务规则模型,这个选项 "可能 "工作,但它可能不是你的领域的最佳解决方案。使用key-value存储的需求主要是 relational 领域,使您不得不做出可能对您不利的权衡。

当你的 user 类有新的字段,而这些字段需要被查询,那么你需要创建更多的 "空间 "来减少 "时间"。你不断地对你的数据进行去规范化处理,只为实现一次查询。你将尝试在key-value存储世界中实现你的关系数据库。当你只需要用一个简单的语句更新你的用户101。

UPDATE users SET username = 'mynewusername' where id = 101;

在你的情况下,你将需要通过所有的哈希集列表找到所有相关的键值并更新它们以保证数据的完整性。保持 age 作为一个字段可能是一个坏主意,你将需要使用生日或,如果你的业务需要获取用户的生日是今天的列表,那么你需要创建新的键,复制你的大部分数据,迁移所有现有的用户到那里,只是得到今天的生日。最好记住这一点,你需要按日和月查询来获取生日--这意味着你必须将用户保存在单独的集合中,如 users:birthday:01:01, users:birthday:02:05, users:birthday:11:08 来获取它们。如果用户想更新自己的生日(取决于业务),那么你需要手动在这些组之间移动用户,同时也更新其他组。

添加 activepassive 给用户带来的将是另一种痛苦。我不知道你是否需要得到 all 用户,你可能需要将他们分页,同时使用哈希 - 这将是困难的,你将需要另一个另一个排序的设置列表来获得。

同样的道理,用户的帖子评论,用户的最近25条评论,发帖最多的用户的最近评论或者搜索用户的帖子等等等等。你的产品经理会出主意的,让我们加上 tag 每篇文章,您需要 relate 在您的数据模型中加入新的数据结构。

这些结构是 relational 数据,最好让它们保持关系型。当你开始在非关系型数据库中对你的数据进行建模时,所有的? elasticity rdbms 你将会消失,取而代之的将是 complexity 在数据层和应用层。

在这个问题上,单一的postgresql可能比redis更能提升你的能力。Redis有很好的功能来解决问题,但userpostcomment不是其中之一。

这个 岗位 也可以提供一些启示

© www.soinside.com 2019 - 2024. All rights reserved.