比较数据类型
提示
来自deepseek解释
原文链接:https://redis.io/docs/latest/develop/data-types/compare-data-types/
Redis 提供了广泛的数据类型来存储您的数据。以下类型高度专业化,适用于特定用途:
- 地理空间:存储带有关联坐标的字符串,用于地理空间查询。
- 概率数据类型:为大型数据集保存近似计数和其他统计数据。
- 时间序列:存储实数值数据点及其收集时间。
- 向量集合:存储带有关联向量数据(和可选元数据)的字符串,用于向量相似性查询。
其余数据类型更通用:
- 字符串:存储文本或二进制数据。
- 数组:通过整数索引寻址存储字符串,支持稀疏索引和服务器端聚合。
- 哈希:在单个键内存储键值对。
- JSON:存储结构化的、层次化的数组和键值对象,匹配流行的 JSON 文本文件格式。
- 列表:存储简单的字符串序列。
- 集合:存储唯一字符串的集合。
- 有序集合:存储带有关联分值的唯一字符串的集合。
- 流:存储条目序列,每个条目包含一组字段-值对。
这些通用数据类型在特性上存在一些重叠,实际上您可能只需使用字符串加上一点创意就能模拟其中任何一种。然而,每种数据类型在性能、内存使用和功能方面提供了不同的权衡。本指南帮助您为您的任务选择最佳数据类型。
数据类型特性
以下各节总结了每种数据类型的特性。
字符串
- 结构:无结构的文本/二进制数据或简单的计数器、位集或整数集合。
- 操作:获取、设置、追加、递增、递减、按位操作。
- 适用场景:无结构文档、计数器、标志、位图。
字符串主要用于存储文本或二进制数据块,其内部结构将由您自己的应用程序管理。但是,它们也支持访问字符串中的位范围,以用作位集、整数或浮点数。
数组
- 结构:稀疏的、可索引寻址的字符串序列。
- 操作:获取、设置、删除、范围读取、范围扫描、顺序插入、聚合。
- 适用场景:事件日志、环形缓冲区、传感器读数,以及其他追加密集或稀疏序列。
数组按整数索引寻址值,无论数组的逻辑大小如何,随机访问都是 O(1)。由于数组是稀疏的,在索引 1,000,000 处设置元素不会为中间的百万个空槽分配内存,因此大的索引间隙成本很低。数组区分逻辑长度(最高已设索引加一,由 ARLEN 返回)和元素数量(非空槽的数量,由 ARCOUNT 返回)。
除了直接索引访问外,数组还通过 ARINSERT 支持顺序插入,该命令自动推进内部游标。游标可以通过 ARSEEK 重新定位,从而实现灵活的追加模式。ARRING 明确表示环形缓冲区模式:它以固定大小为模插入值,当缓冲区满时环绕并覆盖最旧的条目。AROP 在范围上执行单次聚合(求和、最小值、最大值、按位操作、值匹配),而无需逐个获取每个元素。
哈希
- 结构:键值对的集合。
- 操作:获取、设置、删除、递增、递减、查询。
- 适用场景:字段数量较少且没有嵌套或复杂结构的简单对象。
哈希主要用于存储字段数量较少且没有嵌套或复杂结构的对象。但是,哈希中可以存储的字段数量没有实际限制,因此您可以在应用程序中以多种不同方式使用哈希。字段值是字符串,但哈希提供了将它们视为整数或浮点数并执行简单算术运算的命令。您可以为单个哈希字段设置过期时间,还可以使用 Redis Search 索引和查询哈希文档。
JSON
- 结构:层次化的数组和键值对象,匹配流行的 JSON 文本文件格式。
- 操作:获取、设置、更新、删除、查询。
- 适用场景:具有许多字段的复杂嵌套对象。
JSON 提供了丰富的建模能力,支持嵌套字段和数组。您可以使用简单的路径语法访问 JSON 文档中的任意数据子集。与哈希相比,JSON 还具有更强大和灵活的 Redis Search 功能。
列表
- 结构:简单的字符串序列。
- 操作:推入、弹出、获取、设置、修剪。
- 适用场景:队列、栈、日志和其他线性数据结构。
列表存储字符串值的序列。它们针对在头部或尾部添加和移除少量元素进行了优化,因此非常适合实现队列、栈和双端队列。
集合
- 结构:唯一字符串的集合。
- 操作:添加、移除、测试成员资格、交集、并集、差集。
- 适用场景:没有关联数据的唯一项。
集合存储唯一字符串的集合。它们为测试成员资格、添加和移除元素提供了高效的操作。还支持集合操作,如交集、并集和差集。
有序集合
- 结构:带有关联分值的唯一字符串的集合。
- 操作:添加、移除、测试成员资格、按分值或排名范围查询。
- 适用场景:带有分值的唯一项,或有序集合。
有序集合存储带有关联分值的唯一字符串的集合。它们针对基于分值的高效范围查询进行了优化,因此适用于实现优先级队列和其他有序集合。
流
- 结构:条目序列,每个条目包含一组字段-值对。
- 操作:添加、读取、修剪。
- 适用场景:日志数据、时间序列和其他仅追加结构。
流存储条目序列,每个条目包含一组字段-值对。它们针对追加新条目和按顺序读取进行了优化,因此适用于实现日志数据、时间序列和其他仅追加数据结构。它们还内置了对消费者组的支持,用于管理多个读取者并确保至少一次交付。
选择数据类型
以下各节探讨了针对特定任务,每种数据类型的优缺点。请注意,您应将建议视为“经验法则”而非严格的处方,因为在选择数据类型时可能存在许多微妙的理由。
文档
您通常使用字符串、哈希或 JSON 类型存储文档数据。JSON 通常对内存和处理的要求最高,其次是哈希,然后是字符串。使用下面的决策树作为选择最适合您任务的数据类型的指南。
id: documents-tree
scope: documents
rootQuestion: root
questions:
root:
text: |
您需要嵌套数据结构(字段和数组)或使用 Redis Search 进行地理空间索引/查询吗?
whyAsk: |
JSON 是唯一支持深度嵌套结构并将这些结构与 Redis Search 集成的文档类型
answers:
yes:
value: "是"
outcome:
label: "使用 JSON"
id: jsonOutcome
no:
value: "否"
nextQuestion: hashQuestion
hashQuestion:
text: |
您需要使用 Redis Search 进行索引/查询,但可以接受没有嵌套数据结构和地理空间索引吗?
whyAsk: |
哈希支持索引和查询,内存开销更低,字段访问比 JSON 更快
answers:
yes:
value: "是"
outcome:
label: "使用哈希"
id: hashOutcome
no:
value: "否"
nextQuestion: expirationQuestion
expirationQuestion:
text: |
您需要为文档中的单个数据片段设置过期时间吗?
whyAsk: "只有哈希支持高效的字段级访问和过期"
answers:
yes:
value: "是"
outcome:
label: "使用哈希"
id: hashOutcome
no:
value: "否"
nextQuestion: fieldAccessQuestion
fieldAccessQuestion:
text: |
您需要频繁访问文档中的单个数据字段,但字段只是简单的整数或位,您可以轻松地通过整数索引引用它们吗?
whyAsk: |
字符串和哈希都支持高效的字段访问,但如果您只需要带整数索引的位字段,字符串更紧凑高效
answers:
yes:
value: "是"
outcome:
label: "使用字符串"
id: stringOutcome
no:
value: "否"
nextQuestion: stringQuestion
stringQuestion:
text: |
您需要频繁访问文档中具有字符串或二进制数据值的单个数据字段吗?
whyAsk: |
哈希支持通用字段访问,但如果您不需要,字符串更紧凑高效
answers:
yes:
value: "是"
outcome:
label: "使用哈希"
id: hashOutcome
no:
value: "否"
outcome:
label: "使用字符串"
id: stringOutcome集合
您通常使用集合或有序集合类型存储集合数据,对于非常简单的集合,甚至可以使用字符串。它们都支持基本的成员资格测试,但具有不同的附加功能和权衡。有序集合的内存开销和处理要求最高,其次是集合,然后是字符串。使用下面的决策树作为选择最适合您任务的数据类型的指南。请注意,如果您需要为集合或有序集合中的键存储额外信息,可以使用辅助哈希或 JSON 对象,其字段名与集合中的键匹配。
id: collections-tree
scope: collections
rootQuestion: root
questions:
root:
text: |
您需要以任意顺序或字典序存储和检索键吗?
whyAsk: |
有序集合是唯一支持有序迭代的集合类型,如果您需要按特定顺序访问元素,这是必不可少的
answers:
yes:
value: "是"
outcome:
label: "使用有序集合"
id: sortedSetsOutcome
no:
value: "否"
nextQuestion: extraInfo
extraInfo:
text: |
您需要为每个键存储额外信息并且不需要集合操作(并集、交集、差集)吗?
whyAsk: |
哈希允许您为每个键关联数据,但不支持集合操作。如果您同时需要额外数据和集合操作,集合不适用
answers:
yes:
value: "是"
outcome:
label: "使用哈希"
id: hashesOutcome
no:
value: "否"
nextQuestion: integerIndices
integerIndices:
text: |
键是否总是已知范围内的简单整数索引?
whyAsk: |
字符串位图提供最低的内存开销和整数索引的高效随机访问,按位操作等效于集合操作
answers:
yes:
value: "是"
outcome:
label: "使用字符串(位图)"
id: stringsOutcome
no:
value: "否"
outcome:
label: "使用集合"
id: setsOutcome序列
您通常使用有序集合、列表、流或数组存储字符串或二进制数据的序列。它们各有优缺点,适用于不同用途。使用下面的决策树作为选择最适合您任务的数据类型的指南。
id: sequences-tree
scope: sequences
rootQuestion: root
questions:
root:
text: |
您需要维护任意的优先级顺序、字典序,或执行集合操作吗?
whyAsk: |
有序集合是唯一同时支持排序和集合操作的序列类型
answers:
yes:
value: "是"
outcome:
label: "使用有序集合"
id: sortedSetsOutcome
no:
value: "否"
nextQuestion: indexedAccess
indexedAccess:
text: |
您需要通过调用者选择的整数索引(包括稀疏或非连续索引)寻址元素,在索引范围上执行服务器端聚合(求和、最小值、最大值、按位操作),或使用覆盖最旧条目的固定大小环形缓冲区吗?
whyAsk: |
数组将整数索引直接映射到字符串值,具有 O(1) 访问,支持稀疏索引而不分配间隙,并包含列表和流不提供的服务器端聚合和环形缓冲区操作
answers:
yes:
value: "是"
outcome:
label: "使用数组"
id: arraysOutcome
no:
value: "否"
nextQuestion: timestampOrder
timestampOrder:
text: |
您需要主要按时间戳顺序存储和检索元素,或管理从序列中读取的多个消费者吗?
whyAsk: |
流是唯一支持基于时间戳排序和消费者组来管理多个读取者并提供至少一次交付的序列类型
answers:
yes:
value: "是"
outcome:
label: "使用流"
id: streamsOutcome
no:
value: "否"
outcome:
label: "使用列表"
id: listsOutcome