首页 > 解决方案 > Redis 哈希表的使用情况

问题描述

我想使用像 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_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}

通过 pne 反序列化 json 字符串并将它们填充到 list 中,我有 List 所以我可以做一些操作(搜索、groupby、order、pagination ...),我可以为另一个哈希做同样的事情(post、comment)

我可以删除,更新用户;

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 表。

标签: hashredis

解决方案


根据您的业务规则/模型,此选项“可能”有效,但它可能不是您所在领域的最佳/接近最佳解决方案。在需要主要域的情况下使用键/值存储relational会导致您做出权衡,这可能对您不利。

当您的user班级有新字段并且需要查询此字段时,您需要创建更多“空间”以减少“时间”。您不断对数据进行非规范化以实现单个查询。您将尝试在键/值存储世界中实现您的关系数据库。当您只需要用一个简单的语句更新您的用户 101 时;

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

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

向用户添加active/passive将是另一个痛苦。我不确定您是否需要获取all用户,您可能需要对它们进行分页,并且在使用哈希时 - 这会很困难,您将需要另一个排序集/列表来获得它。

用户帖子的评论、用户的最后 25 条评论、帖子最多的用户的最新评论或搜索用户的帖子等也是如此。您的产品经理会提出这个想法,让我们添加tag到每个发布,您将需要relate使用新的数据结构将其放入您的数据模型中。

这些是relational数据,最好保持它们的关系。当您开始在非关系数据库中对数据进行建模时,您所提供的所有内容都将消失,并且在数据和应用程序层上都elasticity rdbms将被替换。complexity

在这个问题上,单个 postgresql 可能比 redis 更好地帮助你。Redis 具有解决问题的出色功能,但用户/帖子/评论不是其中之一。

这篇文章也可能提供一些见解


推荐阅读