Redis 中等效的复合主键
Composite Primary Key equivalent in Redis
我是没有sql 数据库的新手,所以请原谅我的 sql 心态,但我希望存储可以通过 2 个键之一 'queried' 的数据。结构如下:
{user_id, business_id, last_seen_ts, first_seen_ts}
如果这是一个 sql 数据库,我会使用 user_id 和 business_id 作为主复合键。我正在寻找的查询类型是
1.'get all where business_id = x'
2.'get all where user_id = x'
有什么建议吗?我不认为我可以根据上面的 2 种检索类型制作一个简单的二级索引。我查看了 'zadd' 和 'zrange' 之类的命令,但这里实际上并没有涉及任何排序。
对我来说,Redis 的用例是减轻对我的 SQL 数据库的写入和读取,同时该程序计算(在 Redis 中进行存储)最终将写入 SQL 数据库的内容.
在 Redis 中执行此操作的惯用方法是对您要执行的每种查询类型使用 SET
。
在您的情况下,您将创建:
- 每个元组的哈希值(user_id、business_id、last_seen_ts、first_seen_ts)
- 一个名称类似于
user:<user_id>:business:<business_id>
的集合,用于存储此用户和此业务的哈希键(您必须添加带有SADD
的哈希ID)
然后要获取给定用户和企业的所有数据,您必须先获取 SET
内容 SMEMBERS
,然后每隔 HASH
获取 GET
其ID在SET
.
注意:鉴于 OP 的自称经验,出于教育目的,此答案有意简化。
(其中之一) 您需要了解的关于 Redis 的第一件事是您设计数据,以便每个查询都将是您过去认为通过主键访问的内容。从这个意义上说,将 Redis 的键空间(全局字典)想象成这样的关系 table:
很方便
CREATE TABLE redis (
key VARCHAR(512MB) NOT NULL,
value VARCHAR(512MB),
PRIMARY KEY (key)
);
注意:在Redis中,value当然可以不仅仅是String。
请记住这一点,并且与其他采用规范化数据的数据库模型不同,您希望让 Redis 准备好有效地处理您的两个查询。这意味着您将保存数据两次:一次在允许按 ID 搜索企业的主键下,另一次允许按用户 ID 查询。
要回答第一个查询 ("'get all where business_id = x'"),您希望为每个 x
保存相关数据(在Redis 我们使用冒号“:”作为约定的分隔符)——所以对于 x=1 你可能会调用你的键 business:1
,对于 x=a1b2c3 business:a1b2c3
等等。
每个这样的 business:x
键都可以是一个 Redis 集,其中每个成员代表元组的其余部分。所以,如果数据是这样的:
{user_id: foo, business_id: bar, last_seen_ts: 987, first_seen_ts: 123}
你会用 Redis 存储它,比如:
SADD business:bar foo
注意:您可以使用任何您想要的序列化,Set 成员只是字符串。
有了这个,回答第一个查询只是 SMEMBERS business:bar
的问题(或者 SSCAN
对于更大的集合)。
如果您已经完成了,那么您已经知道如何为第二个查询提供服务。首先,为您 SADD user:foo bar
的每个用户(例如 user:foo
)使用一个集合。然后 SMEMBERS
/SSCAN
你就快到家了。
您最后需要的是另一组密钥,但这次您可以使用哈希。每个这样的 Hash 都会存储元组的附加信息,即时间戳。我们可以使用由业务和用户 ID 组成的 "Primary Key"(反之亦然),如下所示:
HMSET foo:bar first 123 last 987
在你得到第一个或第二个查询的结果后,你可以获取相关哈希的内容来完成查询(假设查询 return 时间戳也是如此)。
我是没有sql 数据库的新手,所以请原谅我的 sql 心态,但我希望存储可以通过 2 个键之一 'queried' 的数据。结构如下:
{user_id, business_id, last_seen_ts, first_seen_ts}
如果这是一个 sql 数据库,我会使用 user_id 和 business_id 作为主复合键。我正在寻找的查询类型是
1.'get all where business_id = x'
2.'get all where user_id = x'
有什么建议吗?我不认为我可以根据上面的 2 种检索类型制作一个简单的二级索引。我查看了 'zadd' 和 'zrange' 之类的命令,但这里实际上并没有涉及任何排序。
对我来说,Redis 的用例是减轻对我的 SQL 数据库的写入和读取,同时该程序计算(在 Redis 中进行存储)最终将写入 SQL 数据库的内容.
在 Redis 中执行此操作的惯用方法是对您要执行的每种查询类型使用 SET
。
在您的情况下,您将创建:
- 每个元组的哈希值(user_id、business_id、last_seen_ts、first_seen_ts)
- 一个名称类似于
user:<user_id>:business:<business_id>
的集合,用于存储此用户和此业务的哈希键(您必须添加带有SADD
的哈希ID)
然后要获取给定用户和企业的所有数据,您必须先获取 SET
内容 SMEMBERS
,然后每隔 HASH
获取 GET
其ID在SET
.
注意:鉴于 OP 的自称经验,出于教育目的,此答案有意简化。
(其中之一) 您需要了解的关于 Redis 的第一件事是您设计数据,以便每个查询都将是您过去认为通过主键访问的内容。从这个意义上说,将 Redis 的键空间(全局字典)想象成这样的关系 table:
很方便CREATE TABLE redis (
key VARCHAR(512MB) NOT NULL,
value VARCHAR(512MB),
PRIMARY KEY (key)
);
注意:在Redis中,value当然可以不仅仅是String。
请记住这一点,并且与其他采用规范化数据的数据库模型不同,您希望让 Redis 准备好有效地处理您的两个查询。这意味着您将保存数据两次:一次在允许按 ID 搜索企业的主键下,另一次允许按用户 ID 查询。
要回答第一个查询 ("'get all where business_id = x'"),您希望为每个 x
保存相关数据(在Redis 我们使用冒号“:”作为约定的分隔符)——所以对于 x=1 你可能会调用你的键 business:1
,对于 x=a1b2c3 business:a1b2c3
等等。
每个这样的 business:x
键都可以是一个 Redis 集,其中每个成员代表元组的其余部分。所以,如果数据是这样的:
{user_id: foo, business_id: bar, last_seen_ts: 987, first_seen_ts: 123}
你会用 Redis 存储它,比如:
SADD business:bar foo
注意:您可以使用任何您想要的序列化,Set 成员只是字符串。
有了这个,回答第一个查询只是 SMEMBERS business:bar
的问题(或者 SSCAN
对于更大的集合)。
如果您已经完成了,那么您已经知道如何为第二个查询提供服务。首先,为您 SADD user:foo bar
的每个用户(例如 user:foo
)使用一个集合。然后 SMEMBERS
/SSCAN
你就快到家了。
您最后需要的是另一组密钥,但这次您可以使用哈希。每个这样的 Hash 都会存储元组的附加信息,即时间戳。我们可以使用由业务和用户 ID 组成的 "Primary Key"(反之亦然),如下所示:
HMSET foo:bar first 123 last 987
在你得到第一个或第二个查询的结果后,你可以获取相关哈希的内容来完成查询(假设查询 return 时间戳也是如此)。