【问题标题】:Redis: how to use it similar to multi-tablesRedis:如何使用它类似于多表
【发布时间】:2015-11-10 04:23:49
【问题描述】:

好像Redis在关系型数据库中没有对应“表”的实体。

例如,我必须存储:

(token, user_id) 

(cart_id, token, [{product_id, count}])

如果不分开存储这两者,get 方法会从两者中搜索,这会导致混乱。

对了(cart_id, token, [{product_id, count}])是一个购物车,redis中如何设计这样的数据结构?

【问题讨论】:

标签: redis


【解决方案1】:

好像Redis在关系型数据库中没有对应“表”的实体。

对,因为它不是关系数据库。它是一个非常不同的数据结构服务器,需要不同的方法才能很好地使用。

最终要以预期的方式使用 Redis,您需要考虑关系术语,而是考虑您在代码中使用的数据结构。更具体地说,当您想要使用数据时,您如何需要数据?这将是最有可能将其存储在 Redis 中的方式。

在这种情况下,有几个选项,但哈希方法非常适合这个,所以我会在这里详细说明。

首先,创建一个哈希,命名为users:to:tokens。将用户 ID 作为键存储在散列中,并将值作为令牌存储。接下来创建逆,一个名为“tokens:to:users”的哈希。您可能会同时需要这两者 - 能够从另一个中查找一个 - 而这个基础将提供这一点。

接下来,为您的购物车。这也将是一个哈希:carts:cart_id。在此哈希中,您有 product_id 和计数。

最后是您的第三个哈希token:to:cart,它为购物车 id 构建了一个标记索引。我会更进一步,做user:to:cart 以便能够按用户拉车。

现在关于是否将主题演讲存储在地图中,我倾向于选择“否”。通过仅存储 ID,您可以轻松构建 Redis 购物车密钥,而无需将密钥的完整路径存储在数据存储中,也可以节省内存使用量。

确实,如果可以的话,请为所有 ID 使用整数。通过使用整数,您可以利用 Redis 的整数存储优化来降低内存使用率。存储整数的哈希非常高效且非常快速。

如果需要,您可以使用 Redis 来构建您的 ID。您可以使用INCR 命令为userid:countercartid:countertokenid:counter 等每种数据类型构建一个计数器。当INCR 返回新值时,您只需调用一次即可递增并获取新 ID,如果您想快速查看已创建的购物车数量,get cartid:counter 将始终为您提供最大的 ID。有点整洁,IMO。

现在,棘手的地方在于,如果您想使用过期来自动使购物车过期,而不是让它们“闲逛”直到您想清理它们。通过在购物车哈希(具有产品、计数映射)上设置过期时间,您的购物车将自动过期。但是,他们的引用仍将挂在 token:to:cart 哈希中。删除它是一个简单的周期性任务,它处理token:to:cart 的成员并对购物车的键进行exists 检查。如果它不存在,则从哈希中删除它。

【讨论】:

  • IMO 被低估的答案。谢谢!
【解决方案2】:

Redis 是一种键值对存储。来自redis.io

Redis 是一种开源(BSD 许可)的内存数据结构 store,用作数据库、缓存和消息代理。它支持数据 结构,例如字符串、哈希、列表、集合、排序集合 范围查询、位图、超日志和地理空间索引 半径查询。

因此,如果您想存储两种不同的类型(tokens 和 carts),则需要为不同的数据类型存储两个键。例如:

127.0.0.1:6379> hset tokens.token_id@123 user user123
(integer) 1
127.0.0.1:6379> hget tokens.token_id@123 user
"user123" 

其中tokens 是仅用于标记的命名空间。它存储为 Redis-Hash:

Redis 哈希是字符串字段和字符串值之间的映射,因此它们 是表示对象的完美数据类型

要存储列表,我会执行以下操作:

127.0.0.1:6379> hmset carts.cart_1 token token_id@123 cart_contents cart_contents_key1
OK 
127.0.0.1:6379> hmget carts.cart_1 token cart_contents
1) "token_id@123"
2) "cart_contents_key1"  # cart_contents is a list of receipts.

cart_contents 表示为 Redis-List:

127.0.0.1:6379> rpush cart_contents.cart_contents_key1 receipt_key1
(integer) 1
127.0.0.1:6379> lrange cart_contents.cart_contents_key1 0 -1
1) "receipt_key1"

Receipt 是一个元组的 Redis-Hash (product_id, count):

127.0.0.1:6379> hmset receipts.receipt_key1 product_id 43 count 2
OK
127.0.0.1:6379> hmget receipts.receipt_key1 product_id count
1) "43"  # Your final product id.
2) "2"

但是在这种情况下你真的需要 Redis 吗?

【讨论】:

    猜你喜欢
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多