redis中的定长数据结构
Fixed length data structures in redis
我需要用大约一个或多个布尔值匹配数万个 4 字节字符串。如果这意味着更快的检索,我不介意用一个完整的词来表示布尔值。然而,我对我的数据有如此严格的限制,我想如果提前将这些报告给存储引擎,可以进行一些优化,尽管很小。 Redis有没有办法利用这个?
这是我的数据示例:
"DENL": false
"NLES": false
"NLUS": true
"USNL": true
"AEGB": true
"ITAE": true
"ITFR": false
键是两个 ISO 3166-1 alpha-2 codes 的串联。因此它们保证是4个大写英文字母。
我考虑使用的数据结构是:
- 将 4 字节键映射到表示布尔值的字符串的哈希值
- 每个布尔值单独设置
并且因为我的数据只包含大写英文字母,并且只有 456976 种可能的组合(每个键存储的每位存储量为 56KB):
- 通过按位运算(GETBIT、BITFIELD)访问的一个或多个字符串,使用函数将键字符串转换为位索引。
我认为集合可能是最优雅的解决方案,所有可能组合的二进制字符串将是最有效的。我想知道是否有某种中间立场?就像一个以固定长度字符串作为成员的集合。我希望针对固定长度字符串优化的数据类型能够提供比针对可变长度字符串优化的数据类型更快的搜索。
您可以尝试一些优化:
- 使用一组并将所有值视为 "need customs declaration" 或 "does not need a customs declaration" - 取决于哪个值较少;然后用 SISMEMBER 你可以检查你的密钥是否在那个给你正确答案的集合中,
- 查看 introduction to Redis data types, chapter "Bitmaps" - if you pre-define all of your keys in some array you can use SETBIT and GETBIT 操作以存储给定位数(数组中的索引)的标志 "needs customs declaration"。
最好使用 4 个字母的国家/地区代码组合作为简单键,并使用空值。
set 数据类型实际上是一个散列映射,其中键是元素,并以 NULL 值添加到散列映射中。我不会使用 set 因为这意味着哈希和两次查找到哈希映射:第一个用于数据库中的 set 键和第二个用于元素的 set 内部哈希。
如 Tomasz 所说,使用密钥的存在作为 "need customs declaration" 或 "does not need a customs declaration"。
使用简单的键允许您使用带有 NX/XX 条件的 SET 命令,这在您的逻辑中可能很方便:
- NX -- 仅在密钥不存在时才设置它。
- XX -- 仅在密钥已存在时设置。
使用 EXISTS
命令代替 GET
,因为它稍微快一些(没有类型检查,没有取值)。
简单键与 sets 相比的另一个优点是使用 MGET
:
一次获取多个键的值
> MGET DENL NLES NLUS
1) ""
2) ""
3) (nil)
为了能够进行复杂的查询,假设这些查询很少见并且没有针对性能进行优化,您可以使用 SSCAN
(如果您使用 sets)或 KEYS (如果你使用简单的键)。但是,如果您使用简单的密钥,则最好使用专用数据库,请参阅 SELECT
。
要查询左侧带有 NL 的那些,您可以使用:
KEYS NL??
我需要用大约一个或多个布尔值匹配数万个 4 字节字符串。如果这意味着更快的检索,我不介意用一个完整的词来表示布尔值。然而,我对我的数据有如此严格的限制,我想如果提前将这些报告给存储引擎,可以进行一些优化,尽管很小。 Redis有没有办法利用这个?
这是我的数据示例:
"DENL": false
"NLES": false
"NLUS": true
"USNL": true
"AEGB": true
"ITAE": true
"ITFR": false
键是两个 ISO 3166-1 alpha-2 codes 的串联。因此它们保证是4个大写英文字母。
我考虑使用的数据结构是:
- 将 4 字节键映射到表示布尔值的字符串的哈希值
- 每个布尔值单独设置
并且因为我的数据只包含大写英文字母,并且只有 456976 种可能的组合(每个键存储的每位存储量为 56KB):
- 通过按位运算(GETBIT、BITFIELD)访问的一个或多个字符串,使用函数将键字符串转换为位索引。
我认为集合可能是最优雅的解决方案,所有可能组合的二进制字符串将是最有效的。我想知道是否有某种中间立场?就像一个以固定长度字符串作为成员的集合。我希望针对固定长度字符串优化的数据类型能够提供比针对可变长度字符串优化的数据类型更快的搜索。
您可以尝试一些优化:
- 使用一组并将所有值视为 "need customs declaration" 或 "does not need a customs declaration" - 取决于哪个值较少;然后用 SISMEMBER 你可以检查你的密钥是否在那个给你正确答案的集合中,
- 查看 introduction to Redis data types, chapter "Bitmaps" - if you pre-define all of your keys in some array you can use SETBIT and GETBIT 操作以存储给定位数(数组中的索引)的标志 "needs customs declaration"。
最好使用 4 个字母的国家/地区代码组合作为简单键,并使用空值。
set 数据类型实际上是一个散列映射,其中键是元素,并以 NULL 值添加到散列映射中。我不会使用 set 因为这意味着哈希和两次查找到哈希映射:第一个用于数据库中的 set 键和第二个用于元素的 set 内部哈希。
如 Tomasz 所说,使用密钥的存在作为 "need customs declaration" 或 "does not need a customs declaration"。
使用简单的键允许您使用带有 NX/XX 条件的 SET 命令,这在您的逻辑中可能很方便:
- NX -- 仅在密钥不存在时才设置它。
- XX -- 仅在密钥已存在时设置。
使用 EXISTS
命令代替 GET
,因为它稍微快一些(没有类型检查,没有取值)。
简单键与 sets 相比的另一个优点是使用 MGET
:
> MGET DENL NLES NLUS
1) ""
2) ""
3) (nil)
为了能够进行复杂的查询,假设这些查询很少见并且没有针对性能进行优化,您可以使用 SSCAN
(如果您使用 sets)或 KEYS (如果你使用简单的键)。但是,如果您使用简单的密钥,则最好使用专用数据库,请参阅 SELECT
。
要查询左侧带有 NL 的那些,您可以使用:
KEYS NL??