1. ホーム
  2. スクリプト・コラム
  3. ルア

Redisチュートリアル(3)。データ型の一覧

2022-02-12 11:36:17

I. 概要

      Redisでは、List型は挿入順でソートされた文字列の連鎖である。データ構造の通常のリンクテーブルのように、その先頭(左)と最後尾(右)に新しい要素を追加することができます。挿入時に、キーが存在しない場合、Redisはそのキーに対して新しいリンクドテーブルを作成します。一方、連鎖の要素がすべて削除されると、そのキーもデータベースから削除されます。Listに含まれる要素の最大数は4294967295個です。
      要素の挿入・削除の効率という観点から、連鎖表の両端で要素の挿入・削除を行うのであれば、連鎖表にすでに数百万行が格納されていても、定時で行える非常に効率の良い操作になります。ただし、要素の挿入や削除の操作をチェーンテーブルの途中で行うと、非常に非効率になることに注意する必要があります。これは、データ構造の基礎がある開発者であれば、理解するのは難しくないことだと思います。

II. 関連コマンドの一覧です。

<テーブル コマンドプロトタイプ 時間的複雑性 コマンドの説明 戻り値 LPUSH キー値 [値 ...]  O(1) 指定されたキーに関連付けられたリスト値の先頭に、パラメータで指定されたすべての値を挿入します。キーが存在しない場合、コマンドは挿入前にキーに関連付けられた空のチェーンテーブルを作成し、後でチェーンテーブルの先頭からデータを挿入します。KeyのValueがリンクされたテーブルのタイプでない場合、コマンドは関連するエラーメッセージを返します。  挿入後のリンク先テーブルの要素数。 LPUSHX  キー値  O(1)   このコマンドは、パラメータで指定された Key が存在する場合のみ、パラメータで指定された Value を関連する List Value のヘッダーに挿入します。 挿入後のリンク先テーブルの要素数。  LRANGE  キースタートストップ  O(S+N) 時間複雑性のSはstartパラメータで示されるオフセット、Nは要素数である。このコマンドのパラメータ start と end はともに 0 ベースです。つまり、0 はチェーンの先頭(左端)にある最初の要素を示します。startの値は負の値も可能で、-1は連鎖表の最後の要素、つまり末尾の要素を示し、-2は最後尾の要素を示し、以下同様である。このコマンドで要素を取り出すと、開始位置と終了位置にある要素も取り出されます。startの値が鎖表の要素数より大きい場合は、空の鎖表が返されます。endの値が要素数より大きい場合は、startから始まりendを含むチェーン内の残りの要素をすべて取り出します。 指定された範囲内の要素のリストを返します。 LPOP キー  O(1)  指定されたキーに関連するチェーンテーブルの最初の要素 (ヘッド要素) を返し、ポップします。キーが格納されていない場合はnilを返す。 チェーンテーブルの先頭にある要素。 LLEN キー O(1)  指定された Key に関連する連鎖表の要素数、または Key が存在しない場合は 0、そして Key に関連する Value のタイプが連鎖表でない場合は関連するエラーメッセージを返します。 リンク先テーブルの要素数。 LREM キーカウント値  O(N)  時間複雑性のNは、チェーンテーブルの要素数を示す。指定されたKeyに関連付けられた連鎖表において、値がvalueと等しい要素の最初のカウントを削除する。countが0より大きい場合、headからtailまで走査して削除し、countが0より小さい場合、tailからheadまで走査して削除する。countが0に等しい場合,chainテーブル中のvalueと等しい要素を全て削除する。指定されたKeyが存在しない場合は、直接0を返す。 削除された要素の数を返します。 LSET キーインデックス値  O(N)  時間計算量のNは、チェインテーブルの要素数を示す。しかし、先頭または末尾の要素を設定する場合、時間複雑度はO(1)である。チェーンテーブルの指定された位置の値を新しい値に設定する。ここで、0は最初の要素、ヘッド要素、-1はテール要素を示す。インデックス値Indexがチェインテーブルの要素数の範囲外である場合、このコマンドは関連するエラーメッセージを返す。 LINDEX  キーインデックス  O(N)  時間の複雑さのNは、要素を見つけるために走査される要素の数を示します。先頭または末尾の要素の場合、時間計算量はO(1)である。このコマンドは、チェーンテーブルの指定された位置(インデックス)にある要素を返します。インデックスが0ベースの場合はヘッドエレメントを示し、インデックスが-1の場合はテールエレメントを示す。Keyがリンクされたテーブル以外のものと関連付けられている場合、このコマンドは関連するエラーメッセージを返します。 要求された要素を返します。indexが範囲外の場合はnilを返します。 LTRIM キースタートストップ  O(N)  Nは削除する要素の数を示します。このコマンドは指定された範囲内の要素のみを保持するため、リンク内の要素数を比較的一定に保つことができます。 startとstopのパラメータはいずれも0ベースで、0は先頭の要素を表します。他のコマンドと同様、startとstopには負の値も指定でき、-1なら末尾の要素を示します。startがチェーンの末尾より大きい場合、またはstopがstopより大きい場合、このコマンドはエラーを報告しませんが、空のチェーンを返し、同時にKeyも削除されます。stopが要素数より大きい場合、startから残っているすべての要素が保持されます。 LINSERT  キー BEFORE|AFTER ピボット値  O(N)  時間の複雑さのNは、要素ピボットを見つけるまでに走査する要素数を表します。つまり、ピボットがチェーン・テーブルの先頭または末尾にある場合、このコマンドの時間複雑度はO(1)になります。このコマンドの機能は、要素ピボットの前または後のパラメータに要素値を挿入することです。キーが存在しない場合、このコマンドは何も実行しません。Key に関連付けられた Value タイプがリンクされたテーブルでない場合、関連するエラー・メッセージが返されます。 挿入に成功した後のリンク・テーブルの要素数。ピボットが見つからなかった場合は -1、キーが存在しない場合は 0 を返します。 RPUSH  キー値 [値 ...]  O(1)  指定されたキーに関連付けられたリスト値の末尾に、パラメータで指定されたすべての値を挿入します。キーが存在しない場合、コマンドは挿入前にキーに関連付けられた空のチェーンテーブルを作成し、その後チェーンテーブルの末尾からデータを挿入します。KeyのValueがリンクされたテーブル・タイプでない場合、コマンドは関連するエラーメッセージを返します。  挿入後のリンク先テーブルの要素数。  RPUSHX  キーバリュー  O(1)  このコマンドは、パラメータで指定されたキーが存在する場合のみ、パラメータで指定された値を関連するリスト値の末尾に挿入し、それ以外の場合は何も行いません。  挿入後のリンク先テーブルの要素数。  RPOP キー  O(1)  指定されたキーに関連するチェーンテーブルの最後の要素であるテールエレメントを返し、ポップします。キーが格納されていない場合はnilを返す。  チェーンテーブルの末尾にある要素。  RPOPLPUSH ソース・デスティネーション  O(1)  ソースキーに関連付けられたチェーンの末尾から要素を原子的にポップし、ポップされた要素をデスティネーションキーに関連付けられたチェーンの先頭に挿入します。ソース・キーが存在しない場合、このコマンドはnilを返し、他の操作は行いません。sourceとdestinationが同じキーの場合、関連するチェーンの末尾の要素をそのチェーンの先頭にアトミックに移動するのと同じです。 ポップした要素と挿入した要素を返します。

III. コマンドの例

    1. lpush/lpushx/lrange:

コピーコード コードは以下の通りです。

    /> redis-cli # Start the redis client tool at the shell prompt.
    redis 127.0.0.1:6379> del mykey
    (integer) 1
    #mykey key does not exist, this command creates the key and its associated List, and then inserts the values in the parameters from left to right.
    redis 127.0.0.1:6379> lpush mykey a b c d
    (integer) 4
    #Take the 3 elements starting at position 0 and ending at position 2.
    redis 127.0.0.1:6379> lrange mykey 0 2
    1) "d"
    2) "c"
    3) "b"
    #Fetch all the elements of the chain table, where 0 means the first element and -1 means the last element.
    redis 127.0.0.1:6379> lrange mykey 0 -1
    1) "d"
    2) "c"
    3) "b"
    4) "a"
    The #mykey2 key does not exist at this time, so the command will not perform any operation and its return value is 0.
    redis 127.0.0.1:6379> lpushx mykey2 e
    (integer) 0
    # You can see that mykey2 does not have any List Value associated with it.
    redis 127.0.0.1:6379> lrange mykey2 0 -1
    (empty list or set)
    #mykey key already exists at this point, so the command inserts successfully and returns the current number of elements in the chain.
    redis 127.0.0.1:6379> lpushx mykey e
    (integer) 5
    # Get the head element of the List Value for this key.
    redis 127.0.0.1:6379> lrange mykey 0 0
    1) "e"

    2. LPOP/LLEN。
コピーコード コードは以下の通りです。

    redis 127.0.0.1:6379> lpush mykey a b c d
    (integer) 4
    redis 127.0.0.1:6379> lpop mykey
    "d"
    redis 127.0.0.1:6379> lpop mykey
    "c"
    # After executing the lpop command twice, the two elements at the head of the chain have been popped, and the number of elements in the chain is 2 at this point
    redis 127.0.0.1:6379> llen mykey
    (integer) 2

   3. lrem/lset/lindex/ltrim:
コピーコード コードは以下の通りです。

    #Prepare test data for the examples that follow.
    redis 127.0.0.1:6379> lpush mykey a b c d a c
    (integer) 6
    #Chain table of variables from head (left) to tail (right), delete 2 elements with value equal to a, return value is the actual number deleted.
    redis 127.0.0.1:6379> lrem mykey 2 a
    (integer) 2
    # See all the elements in the linked table after deletion.
    redis 127.0.0.1:6379> lrange mykey 0 -1
    1) "c"
    2) "d"
    3) "c"
    4) "b"
    #Get the value of the element with index value 1 (the second element in the header).
    redis 127.0.0.1:6379> lindex mykey 1
    "d"
    # Set the value of the element with index value 1 (the second element in the header) to the new value e.
    redis 127.0.0.1:6379> lset mykey 1 e
    OK
    # Check if the setup was successful.
    redis 127.0.0.1:6379> lindex mykey 1
    "e"
    # Index value 6 exceeds the number of elements in the chain table, this command returns nil.
    redis 127.0.0.1:6379> lindex mykey 6
    (nil)
    # The set index value 6 exceeds the number of elements in the chain table, the setting fails and the command returns an error message.
    redis 127.0.0.1:6379> lset mykey 6 hh
    (error) ERR index out of range
    # Only the 3 elements with index values between 0 and 2 are retained, note that both the 0th and 2nd elements are retained.
    redis 127.0.0.1:6379> ltrim mykey 0 2
    OK
    # View the result after trim.
    redis 127.0.0.1:6379> lrange mykey 0 -1
    1) "c"
    2) "e"
    3) "c"

    4. LINSERTです。
コピーコード コードは以下の通りです。

    #Remove the key to facilitate later testing.
    redis 127.0.0.1:6379> del mykey
    (integer) 1
    #Prepare test data for the examples that follow.
    redis 127.0.0.1:6379> lpush mykey a b c d e
    (integer) 5
    # Insert new element a1 in front of a.
    redis 127.0.0.1:6379> linsert mykey before a a1
    (integer) 6
    # Check to see if the insertion was successful, from the result it looks like it was inserted. Note that the index value of lindex is 0-based.
    redis 127.0.0.1:6379> lindex mykey 0
    "e"
    # Insert the new element e2 after e. From the returned result it looks like it has been inserted successfully.
    redis 127.0.0.1:6379> linsert mykey after e e2
    (integer) 7
    # Check again to see if the insertion was successful.
    redis 127.0.0.1:6379> lindex mykey 1
    "e2"
    # Insert a new element before or after a non-existent element, the command operation fails and returns -1.
    redis 127.0.0.1:6379> linsert mykey after k a
    (integer) -1
    # Insert a new element for a non-existent Key. The command operation fails and returns 0.
    redis 127.0.0.1:6379> linsert mykey1 after a a2
    (integer) 0

    5. rpush/rpushx/rpop/rpoplpush。
コピーコード コードは以下の通りです。

    #Remove the key for later testing.
    redis 127.0.0.1:6379> del mykey
    (integer) 1
    # Inserts the values given in the argument from the end of the chain, in order of insertion from left to right.
    redis 127.0.0.1:6379> rpush mykey a b c d
    (integer) 4
    # By lrange's you can learn the insertion order of rpush when inserting multiple values.
    redis 127.0.0.1:6379> lrange mykey 0 -1
    1) "a"
    2) "b"
    3) "c"
    4) "d"
    # The key already exists and contains 4 elements, the rpushx command will execute successfully and insert element e to the end of the chain.
    redis 127.0.0.1:6379> rpushx mykey e
    (integer) 5
    #The lindex command shows that the previous rpushx command did execute successfully, because the element with index 4 is now a new element.
    redis 127.0.0.1:6379> lindex mykey 4
    "e"
    # Since the mykey2 key does not exist, the command does not insert data and its return value is 0.
    redis 127.0.0.1:6379> rpushx mykey2 e
    (integer) 0
    #Before executing the rpoplpush command, look at what elements of the chain table are in mykey and note their positional relationship.
    redis 127.0.0.1:6379> lrange mykey 0 -1
    1) "a"
    2) "b"
    3) "c"
    4) "d"
    5) "e"
    # pop the trailing element e of mykey and insert it into the head of mykey2 at the same time (atomically completing these two steps).
    redis 127.0.0.1:6379> rpoplpush mykey mykey2
    "e"
    # View the result of mykey after popping up the trailing element with the lrange command.
    redis 127.0.0.1:6379> lrange mykey 0 -1
    1) "a"
    2) "b"
    3) "c"
    4) "d"
    # View the result of mykey2 after inserting elements by lrange command.
    redis 127.0.0.1:6379> lrange mykey2 0 -1
    1) "e"
    # Set source and destination to the same key, and move the trailing element in mykey to its head.
    redis 127.0.0.1:6379> rpoplpush mykey mykey
    "d"
    # View move results.
    redis 127.0.0.1:6379> lrange mykey 0 -1
    1) "d"
    2) "a"
    3) "b"
    4) "c"

IV. リンクされたテーブル構造のためのヒント。

      リンクされたテーブル構造の値については、Redisはその公式ドキュメントでいくつかの有用なヒントを与えています。例えば、RPOPLPUSHコマンドで、以下に詳しく説明します。
      Redisのチェーニングテーブルは、複数のアプリケーション間のメッセージ交換を実現するために、メッセージキューのサービスでよく使われます。あるアプリケーションがチェインに新しい要素を追加するために LPUSH 操作を行っているとします。通常、このようなアプリケーションを "Producer" と呼び、別のアプリケーションがチェインから要素を削除するために RPOP 操作を行っているとします。メッセージ要素を削除した直後にコンシューマプログラムがクラッシュした場合、メッセージが削除され、適切に処理されていないため、メッセージが失われたと考えることができ、ビジネスデータの損失やビジネスステータスの不整合につながる可能性があります。しかし、RPOPLPUSHコマンドを使用することにより、コンシューマ・プログラムは、メイン・メッセージ・キューからメッセージを削除した後、バックアップ・キューに挿入し、コンシューマ・プログラムが通常の処理論理を完了してから、バックアップ・キューからメッセージを削除するまで、メッセージを挿入することができます。また、バックアップ・キューにあるメッセージが期限切れであることが判明した場合に、メイン・メッセージ・キューに再び挿入し、他のコンシューマ・プログラムが処理を継続できるようにするデーモンも提供することができる。