Maison >base de données >Redis >Parlons du type de données de hachage dans Redis et de comment le faire fonctionner ?

Parlons du type de données de hachage dans Redis et de comment le faire fonctionner ?

青灯夜游
青灯夜游avant
2021-12-31 10:16:252561parcourir

Cet article vous amènera à comprendre le type de données de hachage dans Redis et à présenter les opérations de base des données de type de hachage. J'espère qu'il vous sera utile !

Parlons du type de données de hachage dans Redis et de comment le faire fonctionner ?

1. Présentation des données de type de hachage

Regardons d'abord cet exemple

Dans la section précédente, nous avons découvert le type de stockage de chaîne. Cependant, si le stockage des données d'objet nécessite des mises à jour fréquentes, l'opération sera fastidieuse. Par exemple : user:id:100 -> {"id":100,"name":"Gala de la Fête du Printemps","fans":12355,"blogs":99,"focus:83} code>, si vous devez mettre à jour les données locales dans un objet, vous devez remplacer toutes les données, vous disposez donc des exigences suivantes [Recommandations associées : <a href="http://www.php.cn/course/.%20list/54.html.%20" target="_blank">Tutoriel vidéo Redis</a>]<code>user:id:100 -> {"id":100,"name":"春晚","fans":12355,"blogs":99,"focus:83},如果需要更新一个对象中的局部数据,就需要替换掉所有数据,于是有了以下的需求。【相关推荐:Redis视频教程

新的需求:对一系列存储的数据进行编组,方便管理,比如存储一个对象的信息需要的存储结构:一个存储空间保存多个键值对数据

如下图:

Parlons du type de données de hachage dans Redis et de comment le faire fonctionner ?

为了解决这个问题,我们引入新的数据类型:hash。同时 hash 存储结构也做了以下优化

  • 如果 field 数量较小,存储结构优化为类数组结构
  • 如果 field 数量较多,存储结构使用 HashMap 结构

2. hash 类型数据的基本操作

  • 修改/添加数据
hset key field value
  • 查询单个字段/查询所有字段
# 查询单个字段数据
hget key field
# 查询所有数据
hgetall key
  • 删除操作
hdel key field1 [field2]
  • 修改/添加多个数据
hmset key field1 value1 field2 value2
  • 返回 hash 表中,一个或多个给定字段的值
hmget key field1 field2
  • 获取 hash 表中字段的数量
hlen key
  • 获取 hash 表中是否存在指定的字段
hexists key field

3. hash 类型数据的扩展操作

  • 获取 hash 表中所有字段名或字段值
hkey key
hvals key
  • 设置指定字符段的数值数据增加指定范围的值
hincrby key field increment
hincrbyfloat key field increment

hash 类型数据操作注意事项

  • hash 类型下的 value 只能存储字符串,不允许存储其他数据类型,不存在嵌套对象。如果数据未获取到,对应的结果为(nil);

  • 每个 hash 可以存储 2 的 32 次方减 1 个键值对;

  • hash 类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象属性,但 hash 设计初衷不是为了存储大量对象而设计,切记不可滥用,更不可以将 hash 作为对象列表使用;

  • hgetall 操作可以获取全部属性,如果内部 field 过多,遍历整个数据效率会很低,有可能成为数据访问瓶颈。

4. hash的应用案例

4.1. 用hash实现购物车

概述

在这里我们不讨论购物车与数据库间的持久化同步,也不讨论购物车与订单之间的关系,同时忽略未登录用户购物车信息存储。我们仅仅用 redis 的存储模型来 对购物车 的条目进行 添加、浏览、更改数量、删除、清空

实现方案

  • 以客户 id 作为 key,每位用户创建一个 hash 存储结构对应购物车信息
  • 将商品编号作为 field,购买数量作为 value 进行存储
  • 添加商品:追加全新的 field 与 value
  • 浏览商品:遍历 hash
  • 更改数量:自增/自减,设置 value 值
  • 删除商品:删除 field
  • 清空:删除 key

示例代码如下:

# 001 用户购买 ID为101商品 100件,ID为102的商品 200件
hmset 001 101 100 102 200
# 002 用户购买 ID为102商品 1件,ID为104的商品 7件
hmset 002 102 1 104 7

商品信息加速

当前仅仅是将数量存储到 redis 中,并没有起到加速作用,因为商品信息还需要查询数据库。可以使用以下方案解决:

每条购物车中的商品信息记录保存为两个 field

  • field1 专门用于保存数量

命名格式:商品 id:nums 保存数据:数值

  • field2 专门用于保存购物车中显示的商品信息,包含文字描述,图片地址,所属商家信息等

命名格式:商品 id:info 保存数据:json

示例代码如下:

# 001 用户 购买 ID为101的商品 2件,商品的信息为:{"name":"good name"} 
hmset 001 101:num 2  101:info "{\"name\":\"goods name\"}"
# 002 用户 购买 ID为101的商品 1件,商品的信息为:{"name":"good name"} 
hmset 002 101:num 1  101:info "{\"name\":\"goods name\"}"

在上面的101:info 对应的值中,字符串包含了空格,所以用双引号引用起来,达到转义的目的。

商品信息独立保存

由于 field2 可能在多条商品记录中存在,因此 field2 里的数据可保存到独立的 hash。此时,如果每添加一条购物车记录,就保存一次 hash 数据,显然是不合理的,可以通过hsetnx

Nouvelles exigences : Regroupement d'une série de données stockées pour faciliter la gestion, comme le stockage d'informations sur un objet. Nécessite une structure de stockage : un espace de stockage stocke plusieurs paires clé-valeur

comme indiqué ci-dessous :

Parlons du type de données de hachage dans Redis et de comment le faire fonctionner ?🎜🎜Afin de résoudre ce problème, nous introduisons un nouveau type de données : hash. en même temps, la structure de stockage de hachage a également été créée. L'optimisation suivante🎜
  • Si le nombre de champs est petit, la structure de stockage est optimisée pour être une structure de type tableau
  • Si le le nombre de champs est grand, la structure de stockage utilise la structure HashMap

2 Opérations de base des données de type hachage🎜
  • Modifier/. ajouter des données
hsetnx key field value
  • Interroger un seul champ/interroger tous les champs
# 将id为101 的商品独立存起来
hsetnx info 101 "{\"name\":\"goods name\"}"
  • Opération de suppression
# p01商家下,c30充值券1000张,c50充值券1000张,c100充值券1000张
hmset p01 c30 1000 c50 1000 c100 1000
  • Modifier/ajouter plusieurs données
# p01商家,商品c30售出1件
hincrby p01 c30 -1
# p01商家,商品c100售出20件
hincrby p01 c100 -20
  • Renvoyer la valeur d'un ou plusieurs champs donnés dans la table de hachage
rrreee

  • Obtenir le nombre de champs dans la table de hachage
  • rrreee
  • Obtenir si le champ spécifié existe dans la table de hachage
  • rrreee

    3. Opérations étendues pour les données de type de hachage🎜
    • Obtenez tous les noms de champs ou valeurs de champ dans la table de hachage
    rrreee
    • Définissez les données numériques du champ de caractères spécifié et augmentez la valeur de la plage spécifiée
    rrreee🎜Données de type de hachage Notes d'opération🎜
    • 🎜La valeur sous le type de hachage peut stocke uniquement des chaînes, les autres types de données ne sont pas autorisés et il n'y a pas d'objets imbriqués. Si les données ne sont pas obtenues, le résultat correspondant est (nil) 🎜
    • 🎜Chaque hachage peut stocker 2 à la puissance 32 moins 1 paire clé-valeur 🎜
    • 🎜hash ; Le type est très proche de la forme de stockage des données de l'objet, et les attributs de l'objet peuvent être ajoutés et supprimés de manière flexible. Cependant, l'intention initiale du hachage n'est pas de stocker un grand nombre d'objets. N'oubliez pas de ne pas en abuser, et encore moins de l'utiliser. hachage en tant que liste d'objets ; 🎜
    • 🎜l'opération hgetall peut obtenir tous les attributs. S'il y a trop de champs internes, parcourir l'intégralité des données sera inefficace et peut devenir un goulot d'étranglement pour l'accès aux données. 🎜

    4. Cas d'application du hachage🎜

    4.1 Utiliser le hachage pour implémenter le panierh3 >🎜Aperçu🎜🎜Ici, nous ne discutons pas de la synchronisation persistante entre le panier et la base de données, ni de la relation entre le panier et la commande, et ignorons le stockage des informations du panier pour des raisons non liées. -Utilisateurs connectés. Nous utilisons uniquement le modèle de stockage Redis pour ajouter, parcourir, modifier la quantité, supprimer, effacer🎜🎜Plan de mise en œuvre🎜
    • aux articles du panier . L'ID client est utilisé comme clé et chaque utilisateur crée une structure de stockage de hachage correspondant aux informations du panier.
    • Stockage du numéro de produit comme champ et de la quantité achetée comme valeur
    • <. li>Ajouter un produit : ajouter un nouveau champ et une nouvelle valeur
    • Parcourir les produits : traverser le hachage
    • Modifier la quantité : incrémenter/décrémenter automatiquement, définir la valeur
    • Supprimer le produit : supprimer le champ
    • Effacer : touche Supprimer
    🎜L'exemple de code est le suivant : 🎜rrreee🎜Accélération des informations sur le produit🎜🎜Actuellement, il stocke uniquement la quantité dans redis et ne joue pas de rôle d'accélération, car les informations sur le produit doivent également interroger la base de données. La solution suivante peut être utilisée : 🎜🎜L'enregistrement des informations sur le produit dans chaque panier est enregistré sous forme de deux champs🎜
    • Le champ 1 est spécialement utilisé pour enregistrer la quantité
    🎜Format de dénomination : produit identifiant : numéros Enregistrer les données : valeur numérique 🎜
    • Field2 est spécialement utilisé pour enregistrer les informations sur le produit affichées dans le panier, y compris la description textuelle, l'adresse de l'image, les informations sur le marchand, etc.
    🎜Format de dénomination : identifiant du produit : info Sauvegarder les données : json🎜🎜L'exemple de code est le suivant : 🎜rrreee🎜Dans la valeur correspondant à 101:info ci-dessus, la chaîne contient des espaces, elle est donc entre guillemets doubles pour atteindre l'objectif de s'échapper. 🎜🎜Les informations sur le produit sont enregistrées indépendamment🎜🎜Étant donné que le champ 2 peut exister dans plusieurs enregistrements de produits, les données du champ 2 peuvent être enregistrées dans un hachage indépendant. À l'heure actuelle, il est évidemment déraisonnable de sauvegarder les données de hachage à chaque fois qu'un enregistrement de panier est ajouté. Vous pouvez sauvegarder les données via l'opération hsetnx. Si les données existent, l'opération de sauvegarde ne sera pas effectuée. effectué. 🎜🎜Le format de la commande est le suivant🎜rrreee🎜L'exemple de code est le suivant🎜
    # 将id为101 的商品独立存起来
    hsetnx info 101 "{\"name\":\"goods name\"}"

    4.1. 用hash实现抢购

    案例:双 11 活动日,销售手机充值卡的商家对移动、联通、电信的 30 元、50 元、100 元商品推出抢购活动,每种商品的抢购上限为 100。

    解决方案

    • 以商家 id 作为 key
    • 将参与抢购的商品作为 field
    • 将参与抢购的商品数量作为对应的 value
    • 抢购时使用降值的方式控制产品数量
    • 实际业务中还有超卖等实际问题,这里不做讨论

    实现过程

    商品初始信息

    # p01商家下,c30充值券1000张,c50充值券1000张,c100充值券1000张
    hmset p01 c30 1000 c50 1000 c100 1000

    当 c30 售出1件时,值减 1; 当 c100 售出 20 件时,值减 20,如下代码

    # p01商家,商品c30售出1件
    hincrby p01 c30 -1
    # p01商家,商品c100售出20件
    hincrby p01 c100 -20

    5. string 存对象对比 hash 存对象

    • string 存储 json 字符串:读取方便,在更新的时候会整体进行更新

    • hash 存对象具体的字段:更新灵活

    引入 hash 数据类型之后,我们就解决了 string 存储对象,更新对象时需要整体更新的问题。

    更多编程相关知识,请访问:编程入门!!

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer