似乎Redis在关系数据库中没有任何与“table”相对应的实体。
例如,我必须存储:
(token, user_id)
(cart_id, token, [{product_id, count}])
如果它没有将那两个存储分开,get
方法将从两者中进行搜索,这会导致混乱。
顺便说一句,(cart_id, token, [{product_id, count}])
是购物车,如何在redis中设计这样的数据结构?
答案 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:counter
,cartid:counter
和tokenid:counter
。当INCR
返回新值时,您只需调用一次增量并获取新ID,如果您想快速查看已创建的购物车数量,get cartid:counter
将始终为您提供最大的ID。有点儿,IMO。
现在,它变得棘手的是,如果你想使用过期来自动过期购物车,而不是让它们“撒谎”,直到你想要清理。通过在购物车哈希(具有产品,计数映射)上设置到期,您的购物车将自动过期。但是,他们的引用仍将在token:to:cart
哈希中挂起。删除这是一个简单的定期任务,它会对token:to:cart
的成员进行处理,并对购物车的密钥进行exists
检查。如果它不存在,请从哈希中删除它。
答案 1 :(得分:1)
Redis是一个键值存储。来自redis.io:
Redis是一种开源(BSD许可),内存数据结构 store,用作数据库,缓存和消息代理。它支持数据 结构,如字符串,散列,列表,集合,排序集合 范围查询,位图,超级日志和地理空间索引 半径查询。
因此,如果要存储两种不同类型(token
和cart
),则需要为不同的数据类型存储两个密钥。例如:
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_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吗?