redis哈希表用法

xlpyo6sf  于 2021-06-09  发布在  Redis
关注(0)|答案(1)|浏览(353)

我想使用redis一样的nosql数据库,我有一些想法如下。
假设我有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(\u user\u 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字符串并将它们填入列表之后,我有了一个列表,这样我就可以执行一些操作(搜索、groupby、排序、分页…),并且可以对另一个哈希(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-like nosql表的hash方法。

vlju58qv

vlju58qv1#

根据您的业务规则/模型,此选项“可能”起作用,但可能不是您所在领域的最佳/接近最佳解决方案。在大多数情况下使用键/值存储 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有很好的特性来解决问题,但user/post/comment不是其中之一。
这篇文章也可以提供一些见解

相关问题