hash - 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 表。
解决方案
根据您的业务规则/模型,此选项“可能”有效,但它可能不是您所在领域的最佳/接近最佳解决方案。在需要主要域的情况下使用键/值存储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 具有解决问题的出色功能,但用户/帖子/评论不是其中之一。
这篇文章也可能提供一些见解
推荐阅读
- sql-server - 从 SSIS 集成服务导出项目。现在相同的 ispac 文件重新部署到集成服务目录验证失败
- c# - 回发中清除的选定值
- sapui5 - 使用 detachPress / attachPress 更改按钮上的功能
- javascript - 我想在输入字段中将日期格式更改为 yyyy-mm-dd
- oracle - 需要用外键和主键填充表
- ios - 呈现新 UINavigationController 时出现问题:在 StatusBar 下
- spring - Sprint 启动错误无法获取条目 BOOT-INF/lib/lucene-analyzers-common-7.1.0.jar 的嵌套存档
- vba - 为什么我无法使用 excel VBA 更新 Listbox 的 RowSource 属性?
- javascript - 在JS函数中传递css文件的路径
- java - 无法从单个图像opencv(Java)保存多个图像