[Redis] Exploración en profundidad de los tipos de datos de Redis: hash de tabla hash


Prefacio

El almacenamiento en caché de datos es una de las estrategias clave para mejorar el rendimiento y reducir la carga de la base de datos al crear y optimizar aplicaciones. Redis (Remote Dictionary Server) es una base de datos en memoria de alto rendimiento ampliamente utilizada para el almacenamiento en caché de datos y el acceso rápido a ellos. Entre ellos, el tipo hash (Hash) es una poderosa estructura de datos en Redis, que generalmente se usa para almacenar objetos, mapear relaciones y datos de pares clave-valor.

En este artículo, profundizaremos en los tipos de hash en Redis. Comenzaremos con los comandos básicos del tipo hash y gradualmente introduciremos su uso, codificación interna y aplicación en escenarios de aplicaciones reales. Al aprender y comprender los tipos de hash de Redis, podemos ayudarnos a utilizar mejor Redis para optimizar el almacenamiento y el acceso a datos y mejorar el rendimiento de las aplicaciones.

A continuación, echemos un vistazo más profundo a los tipos de hash de Redis.

1. Comandos relacionados con el tipo de hash

1.1 HSET y HSETNX

  1. HSET
  • Función : establece el valor del campo en la tabla hash especificada. Si el campo existe, se actualizará; de lo contrario, se creará. Y se pueden configurar varios conjuntos de campos al mismo tiempo.

  • gramática:

    HSET key field value [field value ... ]
    
  1. HSETNX
  • Función : establece el valor del campo en la tabla hash especificada solo si el campo no existe. Devuelve 1 si la configuración se realiza correctamente; en caso contrario, devuelve 0.
  • gramática:
    HSETNX key field value 
    
  1. Ejemplo de uso

1.2 HGET y HMGET

  1. HGET
  • Función : obtiene el valor del campo en la tabla hash especificada.
  • gramática:
    HGET key field
    
  1. HMGET
  • Función : obtiene los valores de varios campos en la tabla hash especificada.
  • gramática:
    HMGET key field1 [field2 ...]
    
  1. Ejemplo de uso

Por supuesto, continuaré mejorando las siguientes secciones para cubrir la descripción detallada de los comandos relacionados con el tipo hash:

1.3 HKEYS, BALLENA y HGETAL

  1. HKEYS
  • Función : obtiene los nombres de todos los campos en la tabla hash especificada.
  • Sintaxis :
    HKEYS key
    
  1. HVALS
  • Función : obtiene los valores de todos los campos en la tabla hash especificada.
  • Sintaxis :
    HVALS key
    
  1. HGETALL
  • Función : Obtenga todos los campos y los valores correspondientes en la tabla hash especificada.
  • Sintaxis :
    HGETALL key
    
  1. Casos de uso

1.4 HEXISTAS y HDEL

  1. HEXISTS
  • Función : comprobar si existe un campo en la tabla hash especificada.
  • Sintaxis :
    HEXISTS key field
    
  1. HDEL
  • Función : eliminar uno o más campos en la tabla hash especificada.
  • Sintaxis :
    HDEL key field1 [field2 ...]
    
  1. Casos de uso

1.5 CUMPLIMIENTO

  1. HLEN
  • Función : Obtenga el número de campos en la tabla hash especificada (es decir, el tamaño de la tabla hash).
  • Sintaxis :
    HLEN key
    
  1. Casos de uso

1.6 HINCRBY y HINCRBYFLOAT

  1. HINCRBY
  • Función : aumenta el valor del campo especificado en la tabla hash en un número entero.
  • Sintaxis :
    HINCRBY key field increment
    
  1. HINCRBYFLOAT
  • Función : aumenta el valor del campo especificado en la tabla hash en un número de punto flotante.
  • Sintaxis :
    HINCRBYFLOAT key field increment
    
  1. Casos de uso

1.7 Resumen de comandos relacionados con hash

El siguiente es un resumen de los comandos relacionados con los tipos de hash, incluidos comandos, funciones y complejidad del tiempo:

Orden efecto complejidad del tiempo
HSET Establezca el valor del campo en la tabla hash, actualícelo si existe; de ​​lo contrario, créelo. Se pueden configurar varios conjuntos de campos al mismo tiempo. O(1)
HSETNX Establece el valor del campo en la tabla hash solo si el campo no existe, devolviendo 1 en caso de éxito, 0 en caso contrario. O(1)
HGET Obtiene el valor de un campo en la tabla hash especificada. O(1)
HMGET Obtiene los valores de varios campos en la tabla hash especificada. O(N), N es el número de campos
LLAVES H Obtiene los nombres de todos los campos de la tabla hash especificada. O(N), N es el número de campos
BALLENAS Obtiene los valores de todos los campos de la tabla hash especificada. O(N), N es el número de campos
HGETALL Obtenga todos los campos y los valores correspondientes en la tabla hash especificada. O(N), N es el número de campos
HEXISTAS Comprueba si existe un campo en la tabla hash especificada. O(1)
HDEL Elimine uno o más campos en la tabla hash especificada. O(N), N es el número de campos eliminados
HLEN Obtiene el número de campos de la tabla hash especificada (es decir, el tamaño de la tabla hash). O(1)
HINCRBY Incrementa el valor del campo especificado en la tabla hash en un número entero. O(1)
HINCRBYFLOAT Incrementa el valor del campo especificado en la tabla hash en un número de punto flotante. O(1)

2. Codificación interna de tipo hash.

Redis es una base de datos en memoria de alto rendimiento que admite múltiples estructuras de datos, incluido Hash. En Redis, el tipo de datos hash tiene dos métodos de codificación internos, a saber, ziplist (lista comprimida) y hashtable (tabla hash). La elección entre estos dos métodos de codificación depende del tamaño y las características de almacenamiento del hash.

1. ziplist (lista comprimida):

ziplist es una estructura de datos compacta en Redis para codificar hashes más pequeños internamente. Estas son algunas de las características clave de ziplist:

  • Cuando la cantidad de elementos del tipo hash es relativamente pequeña y todos los campos y valores correspondientes cumplen ciertas restricciones, Redis utilizará ziplist como implementación interna del hash.
  • De forma predeterminada, Redis elige ziplist. Específicamente, ziplist es la codificación preferida si el hash no tiene más de 512 elementos y todos los valores son menores de 64 bytes.
  • Ziplist es una estructura de datos compacta que puede ahorrar memoria mejor que la tabla hash. Almacena múltiples elementos hash juntos de forma continua, lo que reduce efectivamente la huella de memoria.

2. tabla hash:

Hashtable es la codificación interna en Redis para almacenar datos hash a gran escala. Las siguientes son las características clave de la tabla hash:

  • Cuando la cantidad de elementos de tipo hash excede el límite de configuración de ziplist, o el valor correspondiente de un campo es mayor que 64 bytes, Redis cambiará la codificación interna a tabla hash.
  • Hashtable es una estructura de datos de tabla hash, que tiene una complejidad de tiempo de lectura y escritura de O (1) y es adecuada para conjuntos de datos hash a gran escala.
  • Cambiar a tabla hash puede proporcionar un mejor rendimiento y administración de memoria, especialmente cuando se trata de hash grandes o que contienen valores grandes.

Según la descripción anterior, a continuación se muestran algunos ejemplos que demuestran la codificación interna de los tipos de datos hash y bajo qué condiciones se produce la conversión de codificación:

Ejemplo 1: uso de codificación ziplist

> hmset hashkey f1 v1 f2 v2
OK
> object encoding hashkey
"ziplist"

En este ejemplo, dado que la cantidad de campos es pequeña y los valores satisfacen las condiciones, Redis usa ziplist como codificación interna.

Ejemplo 2: cambiar a codificación de tabla hash

> hset hashkey f3 "one string is bigger than 64 bytes ..." 1
OK
> object encoding hashkey
"hashtable"

En este ejemplo, debido a que uno de los campos corresponde a un valor mayor que 64 bytes, Redis cambia la codificación interna a tabla hash.

Ejemplo 3: cambiar a codificación de tabla hash

> hmset hashkey f1 v1 h2 v2 f3 v3 ... (超过 512 个字段) ...
OK
> object encoding hashkey
"hashtable"

En este ejemplo, dado que el número de campos supera los 512, Redis convierte la codificación interna en una tabla hash.

Estas codificaciones internas se eligen para equilibrar el uso de la memoria y el rendimiento en diferentes situaciones. Redis realiza automáticamente estas conversiones de codificación según sea necesario para optimizar el almacenamiento y la eficiencia operativa. Independientemente del tamaño de su conjunto de datos hash, Redis elige de forma inteligente la codificación interna adecuada según la configuración y las características de los datos. Esta optimización automática garantiza un rendimiento excelente de Redis en diversas cargas de trabajo.

3. Escenarios de aplicación de tipo hash

En esta sección, exploraremos los usos prácticos de los tipos de hash en aplicaciones. Primero, revisemos la estructura de la información del usuario almacenada en una base de datos relacional.

Las tablas de datos relacionales almacenan información del usuario.

La figura anterior muestra dos piezas de información del usuario registradas en una tabla de datos relacionales: los atributos del usuario se representan como columnas de la tabla y cada pieza de información del usuario se representa como una fila. Si queremos mapear la información de estos dos usuarios en Redis, podemos usar el tipo hash.

Mapee la información del usuario usando el tipo hash:

La relación de mapeo representa la información del usuario.

En comparación con el uso de cadenas con formato JSON para almacenar en caché la información del usuario, el tipo hash es más intuitivo y más flexible en las operaciones de actualización. Podemos definir la ID de cada usuario como el sufijo de la clave y luego usar múltiples valores de campo para corresponder a cada atributo del usuario, similar al siguiente pseudocódigo:

UserInfo getUserInfo(long uid) {
    
    
    // 根据 uid 得到 Redis 的键
    String key = "user:" + uid;

    // 尝试从 Redis 中获取对应的值
    userInfoMap = Redis 执行命令:hgetall key;

    // 如果缓存命中(hit)
    if (userInfoMap != null) {
    
    
        // 将映射关系还原为对象形式
        UserInfo userInfo = 利用映射关系构建对象(userInfoMap);
        return userInfo;
    }

    // 如果缓存未命中(miss)
    // 从数据库中,根据 uid 获取用户信息
    UserInfo userInfo = MySQL 执行 SQL:select * from user_info where uid = <uid>;

    // 如果表中没有 uid 对应的用户信息
    if (userInfo == null) {
    
    
        响应 404;
        return null;
    }

    // 将缓存以哈希类型保存
    Redis 执行命令:hmset key name userInfo.name age userInfo.age city userInfo.city;

    // 写入缓存,为了防止数据腐烂(rot),设置过期时间为 1 小时(3600 秒)
    Redis 执行命令:expire key 3600;

    // 返回用户信息
    return userInfo;
}

El código anterior demuestra una estrategia de almacenamiento en caché común: primero intenta obtener los datos del caché de Redis, recuperándolos de la base de datos si faltan y almacenando el resultado en Redis para un acceso posterior. Esta estrategia puede mejorar el rendimiento del acceso y reducir la carga de la base de datos.

Sin embargo, es importante tener en cuenta que existen dos diferencias principales entre los tipos de hash y las bases de datos relacionales:

  • La escasez de tipos de hash: los tipos de hash permiten que cada clave tenga campos diferentes, mientras que las bases de datos relacionales necesitan establecer valores para todas las filas al agregar nuevas columnas, incluso las nulas.

  • Inaplicabilidad de consultas relacionales complejas: las bases de datos relacionales admiten consultas relacionales complejas, pero Redis no es adecuado para simular consultas relacionales complejas, como consultas de tablas conjuntas y consultas de agregación, y el costo de mantenimiento es alto.

Ejemplos de escasez en bases de datos relacionales:

Escasez de bases de datos relacionales

A través del tipo hash, podemos mapear y almacenar información del usuario de manera más intuitiva, adaptándonos a las necesidades de diferentes escenarios de aplicación. El uso del tipo hash es simple, intuitivo y flexible, especialmente adecuado para cambios de atributos locales y operaciones de consulta, y también tiene una buena eficiencia de memoria.

4. Comparación de métodos de almacenamiento en caché nativos, serializados y de tipo hash

Cuando se trata de almacenar en caché la información del usuario, existen varios métodos de almacenamiento en caché diferentes para elegir. A continuación se muestra una comparación y un análisis detallados de tres métodos de almacenamiento en caché comunes: tipos de cadenas nativas, tipos de cadenas serializadas (como el formato JSON) y tipos hash. Aquí exploramos sus métodos de implementación, ventajas y desventajas para ayudarlo a elegir mejor la estrategia de almacenamiento en caché que funcione para su aplicación.

4.1 Tipo de cadena nativa

Método de implementación: utilice el tipo de cadena nativa para almacenar cada atributo de usuario como un par clave-valor separado, por ejemplo:

set user:1:name James
set user:1:age 23
set user:1:city Beijing

ventaja:

  • Fácil de implementar, cada propiedad se almacena con una clave separada, fácil de entender y mantener.
  • Muy flexible para cambios de atributos individuales.

defecto:

  • Ocupar demasiadas claves genera una gran huella de memoria.
  • La información del usuario se almacena dispersa en Redis, lo que carece de cohesión y resulta inconveniente para las operaciones y la gestión por lotes.
  • No es adecuado para situaciones en las que es necesario obtener información completa del usuario al mismo tiempo, lo que requiere una gran cantidad de operaciones clave.

Escenarios aplicables: este método es adecuado para escenarios donde se requieren cambios individuales y frecuentes en los atributos del usuario, pero no es adecuado para escenarios donde es necesario obtener información completa del usuario de una sola vez.

4.2 Tipo de cadena serializada (como el formato JSON)

Método de implementación: utilice el tipo de cadena serializada para serializar la información del usuario en formato JSON y almacenarla como un par clave-valor, por ejemplo:

set user:1 {
    
    "name": "James", "age": 23, "city": "Beijing"}

ventaja:

  • Es adecuado para el almacenamiento de información con el conjunto como unidad operativa y la programación es relativamente sencilla.
  • Puede utilizar la memoria de manera eficiente y es particularmente adecuado para almacenar objetos grandes o estructuras de datos.

defecto:

  • La serialización y deserialización requieren cierta sobrecarga.
  • No es adecuado para actualizaciones o consultas frecuentes de atributos individuales y carece de flexibilidad.

Escenarios aplicables: este método es adecuado para escenarios en los que es necesario obtener información completa del usuario al mismo tiempo, especialmente cuando la información del usuario es un objeto o estructura de datos complejos.

4.3 Tipo de hash

Método de implementación: utilice el tipo hash para almacenar información del usuario como tipo hash de Redis, por ejemplo:

hmset user:1 name James age 23 city Beijing

ventaja:

  • Sencillo, intuitivo y flexible.
  • Adecuado para cambios locales u operaciones de adquisición de información, soportando lectura y escritura de atributos individuales.
  • La codificación interna puede ser ziplist o hashtable, lo que tiene mayor flexibilidad y eficiencia de memoria.

defecto:

  • Es necesario controlar la conversión de hash entre las dos codificaciones internas de ziplist y hashtable, lo que puede provocar un consumo de memoria.
  • No es adecuado para situaciones en las que es necesario obtener información completa del usuario de una sola vez y es posible que sea necesario leerla varias veces.

Escenarios aplicables: el tipo hash es adecuado para escenarios donde se requieren cambios locales en los atributos del usuario u operaciones frecuentes de atributos individuales, y también es adecuado para situaciones donde se requieren consultas flexibles de atributos.

4.4 Resumen

La elección del método de almacenamiento en caché adecuado debe determinarse en función de las necesidades específicas de la aplicación y los patrones de acceso. Por lo general, estos tres métodos de almacenamiento en caché pueden considerarse de manera integral en función de diferentes características de datos y requisitos operativos, y combinarse y usarse adecuadamente en aplicaciones para obtener el mejor rendimiento y flexibilidad.

Por ejemplo, se puede usar una caché de tipo hash para manejar consultas y cambios de atributos locales, mientras que se puede usar una caché de tipo cadena serializada para obtener información completa del usuario. De esta manera, las ventajas de Redis se pueden utilizar plenamente para mejorar la eficiencia del acceso a los datos manteniendo la flexibilidad y la mantenibilidad.

Supongo que te gusta

Origin blog.csdn.net/qq_61635026/article/details/132768903
Recomendado
Clasificación