Redis中的固定长度数据结构



我需要将数万个 4 字节字符串与大约一个或多个布尔值匹配。我不介意用完布尔值的整个单词,如果这意味着更快的检索。但是,我对数据有如此严格的限制,我想如果提前将这些优化报告给存储引擎,则可以进行一些优化,尽管这些优化很小。Redis有什么办法可以利用这一点吗?

以下是我的数据示例:

"DENL": false
"NLES": false
"NLUS": true
"USNL": true
"AEGB": true
"ITAE": true
"ITFR": false

键是两个 ISO 3166-1 alpha-2 代码的连接。因此,它们保证为 4 个大写英文字母。

我考虑使用的数据结构是:

  • 将 4 字节键映射到表示布尔值的字符串的哈希
  • 每个布尔值的单独集合

而且由于我的数据只包含大写英文字母,并且只有456976种可能的组合(每个键存储的每位为 56KB(:

  • 使用函数将键字符串转换为位索引的按位运算(GETBIT、BITFIELD(访问的一个或多个字符串。

我认为集合可能是最优雅的解决方案,所有可能的组合上的二进制字符串将是最有效的。我想知道是否有某种中间立场?就像一个以固定长度的字符串作为成员的集合。我希望针对固定长度字符串优化的数据类型能够提供比针对可变长度字符串优化的数据类型更快的搜索。

将 4 个字母的国家/地区代码组合用作具有空值的简单键会稍微好一些。

set数据类型实际上是一个哈希映射,其中键是元素,并被添加到具有 NULL 值的哈希映射中。我不会使用集合,因为这意味着哈希和两个查找到哈希映射中:第一个用于数据库中的set键,第二个用于元素集合的内部哈希。

使用密钥的存在作为"需要报关"或"不需要报关",如Tomasz所说。

使用简单键可以将 SET 命令与 NX/XX 条件一起使用,这在您的逻辑中可能很方便:

  • NX -- 仅当密钥尚不存在时才设置密钥。
  • XX -- 仅当密钥已存在时才设置密钥。

使用EXISTS命令而不是GET,因为它稍微快一些(没有类型检查,没有值获取(。

简单键与集合的另一个优点是使用MGET一次获取多个键的值:

> MGET DENL NLES NLUS
1) ""
2) ""
3) (nil)

为了能够执行复杂的查询,假设这些查询很少见并且没有针对性能进行优化,您可以使用SSCAN(如果使用集合(或 KEYS(如果使用简单键(。但是,如果使用简单密钥,则最好使用专用数据库,请参阅SELECT

要查询左侧有 NL 的用户,请使用:

KEYS NL??

您可以尝试一些优化:

  1. 使用一个集合并将所有值视为"需要报关"或"不需要报关" - 取决于哪一个值较少;然后使用SISMEMBER,您可以检查您的密钥是否在该集中,从而为您提供正确的答案,
  2. 查看 Redis 数据类型简介,"位图"一章 - 如果您在某个数组中预定义了所有键,则可以使用 SETBIT 和 GETBIT 操作来存储给定位号(数组中的索引(的标志"需要海关声明"。

最新更新