Redis:如何使用它类似于多表

时间:2015-11-09 09:21:15

标签: redis

似乎Redis在关系数据库中没有任何与“table”相对应的实体。

例如,我必须存储:

(token, user_id) 

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

如果它没有将那两个存储分开,get方法将从两者中进行搜索,这会导致混乱。

顺便说一句,(cart_id, token, [{product_id, count}])是购物车,如何在redis中设计这样的数据结构?

2 个答案:

答案 0 :(得分:2)

  

似乎Redis在关系数据库中没有任何与“table”相对应的实体。

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

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

在这种情况下有一些选项,但哈希方法对于这个方法非常有效,所以我将在这里详细说明。

首先,创建一个哈希,称之为users:to:tokens。存储为用户id的哈希中的键,以及令牌的值。接下来创建一个反向,一个名为'tokens:to:users'的哈希。你可能会想要这两个 - 从另一个看起来的能力 - 而这个基础会提供这个。

接下来,购物车。这也是一个散列:carts:cart_id。在这个哈希中,你有product_id和count。

最后up是你的第三个哈希token:to:cart,它构建了一个tokens 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检查。如果它不存在,请从哈希中删除它。

答案 1 :(得分:1)

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

  

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

因此,如果要存储两种不同类型(tokencart),则需要为不同的数据类型存储两个密钥。例如:

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 Hashes是字符串字段和字符串值之间的映射,因此它们是   是表示对象的完美数据类型

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

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"

收据是Redis-Hash的元组(product_idcount):

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吗?