我想使用像 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:01
、 users:birthday:02:05
、 users: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/