hash - Redis 哈希表的使用情况

标签 hash redis

我想使用像 Nosql 数据库这样的 redis,我有一些想法,如下所示。

假设我有 3 张 table

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

最佳答案

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

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

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

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

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

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

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

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

这个 post 也可能提供一些见解

关于hash - Redis 哈希表的使用情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61839973/

相关文章:

perl - 如何为散列制造病态 key ?

spring - grails 2.3.5 + redis-gorm 插件 + spring security 核心插件

language-agnostic - 为什么散列函数应该使用质数模数?

algorithm - 哈希值的算术运算

function - 有没有温和的哈希函数教程?

algorithm - 密码存储于2017年

node.js - 无法在 app.get 方法中连接 redis

linux - 打开 RDB 文件失败...只读文件系统

c# - 如何从单个命令中获取多个 Redis 列表

java - 使用 Redis 创建名称为 'enableRedisKeyspaceNotificationsInitializer' 的 bean 时出错