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

Redisチュートリアル(V): データ型を設定する

2022-02-12 23:34:15

I. 概要

      Redisでは、Set型はソートされていない文字の集まりと考えることができ、List型と同様に、その型のデータ値に対して、追加、削除、要素の存在の有無の判定などの操作を行うことができます。Setが含むことのできる要素の最大数は4294967295です。
      リスト型と異なり、セットコレクションでは要素の重複が許されない。これは、C++標準ライブラリのセットコンテナと全く同じである。つまり、同じ要素を複数回追加しても、その要素のコピーは1つしかSetに保持されません。List型と比較した場合のSet型のもう一つの非常に重要な特徴は、複数のSetの集約(結合、交差、差分など)がサーバー側で行われることで、これは非常に効率的でネットワークIOオーバーヘッドを大幅に節約することができます。

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

<テーブル コマンドプロトタイプ 時間的複雑性 コマンドの説明 戻り値 SADD キーメンバー [メンバー ...] O(N) 時間複雑性のNは、操作のメンバー数を示す。挿入処理中に引数のメンバがすでにセット内に存在する場合、そのメンバは無視され、他のメンバはこれまでどおり正常に挿入されます。コマンドの実行前にキーが存在しない場合、コマンドは新しいSetを作成し、引数のメンバを順次挿入していきます。Key の Value が Set 型でない場合、コマンドはエラーメッセージを返します。 この操作で実際に挿入されたメンバーの数。 SCARD キー O(1) Setに含まれるメンバーの数を取得します。 Set 内のメンバーの数を返します。キーが存在しない場合は 0 を返します。 シスメンバー  主要メンバー O(1) 引数の指定されたメンバーが、Keyに関連付けられたSetコレクションに既に存在するかどうかを判定します。 1は既に存在すること、0は存在しないこと、またはKey自体が存在しないことを意味する。 SMEMBERS  キー O(N) 時間の複雑さのNは、Setに既に存在するメンバの数を示します。このキーに関連付けられた Set 内のすべてのメンバを取得します。

Setに含まれるすべてのメンバーを返します。

SPOP キー  O(1)  Setのメンバーをランダムに削除して返します。Setの要素のレイアウトは外部から制御できないので、ListのようにSetの先頭や末尾にある要素を判断することはできません。 削除されたメンバー、またはキーが存在しない場合はnilを返します。 SREM キーメンバー [メンバー ...] O(N)  時間の複雑さのNは、削除されるメンバの数を示します。パラメータで指定されたメンバは、キーに関連付けられたセットから削除されます。存在しないパラメータ・メンバは無視され、キーが存在しない場合は、空のセットとして扱われます。 セットから実際に削除されたメンバーの数、または、何もない場合は0。 SRANDMEMBER  キー  O(1)  SPOPと同様に、Setのランダムなメンバーを返しますが、このコマンドは返されたメンバーを削除しない点が異なります。 ランダムな位置にあるメンバー、またはキーが存在しない場合はnilを返します。 スモーヴ ソース デスティネーション メンバー O(1)  パラメータ内のメンバをソース・キーからデスティネーション・キーに関連付けられたセットにアトミックに移動します。したがって、ある時点で、そのメンバはソースまたはデスティネーションに表示されます。メンバがソースに存在しない場合、このコマンドはそれ以上の処理を実行せず、0 を返します。そうでない場合は、メンバがソースからデスティネーションに移動されます。メンバがデスティネーションに既に存在する場合、コマンドはメンバをソースから移動するだけです。Key に関連付けられた Value が Set でない場合、関連するエラー・メッセージが返されます。 1は正常な移動を示し、0はソースにパラメータメンバが含まれないことを示す。 SDIFF キー [キー ...] O(N)  時間複雑性のNは、すべてのセットのメンバーの総数を表す。引数の最初のキーに関連付けられたセットと、それ以降のすべてのキーに関連付けられたセット内のメンバとの間の差を返します。キーが存在しない場合、それは空のセットと見なされます。 差分結果のメンバーのセット。 SDIFFSTORE デスティネーションキー [キー ...]  O(N)  このコマンドは、SDIFF コマンドと機能的に同じです。2 つの唯一の違いは、SDIFF が差分の結果メンバを返すのに対し、このコマンドは差分メンバを宛先に関連付けられた Set に格納する点です。デスティネーション キーがすでに存在する場合、このアクションによってそのメンバが上書きされます。 diffのメンバー数を返します。 シンター キー [キー ...]  O(N*M)  時間計算のNは最小のSetの要素数、Mは引数のSetの数を表す。このコマンドは、引数のすべてのKeyに関連付けられたSetのメンバーの交差点を返します。したがって、引数のKeyのいずれかに関連付けられたSetが空の場合、またはKeyが存在しない場合、このコマンドの結果は空のSetになります。 交差点の結果メンバーのセット。 シンターストア デスティネーションキー [キー ...] O(N*M)  このコマンドは、機能的には SINTER コマンドと同じです。2 つの唯一の違いは、SINTER が交差点の結果メンバを返すのに対し、このコマンドは交差点メンバを宛先に関連付けられた Set に格納することです。宛先キーが既に存在する場合、この操作によってそのメンバが上書きされます。 交差点のメンバー数を返します。  SUNION  キー [キー ...]  O(N) 時間複雑性のNは、すべてのセットのメンバーの総数を示す。このコマンドは、引数のすべてのキーに関連付けられたセットのメンバの結合を返します。 連結された結果のメンバーのセット。 サニオンストア デスティネーションキー [キー ...]  O(N)  このコマンドは、機能的には SUNION コマンドと同じです。この2つの唯一の違いは、SUNIONが連結されたセットの結果メンバーを返すのに対し、このコマンドは連結されたセットメンバーを宛先に関連付けられたSetに格納することです。宛先のキーがすでに存在する場合、この操作によってそのメンバが上書きされます。  連結されたセットメンバーの数を返します。

III. コマンドの例

   1. sadd/smembers/scard/sismember:

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

    #Start the Redis client application from the shell command line.
    /> redis-cli
    #Insert test data, and since the key myset did not exist before, all three members of the argument are inserted normally.
    redis 127.0.0.1:6379> sadd myset a b c
    (integer) 3
    # Since the a in the argument already exists in myset, this operation only inserts two new members, d and e.
    redis 127.0.0.1:6379> sadd myset a d e
    (integer) 2
    # Determine if a already exists, a return value of 1 means it exists.
    redis 127.0.0.1:6379> sismember myset a
    (integer) 1
    # Determine if f already exists, a return value of 0 means it does not exist.
    redis 127.0.0.1:6379> sismember myset f
    (integer) 0
    # The results of the insertion are viewed with the smembers command, and from the results you can see that the order of the output is independent of the order of insertion.
    redis 127.0.0.1:6379> smembers myset
    1) "c"
    2) "d"
    3) "a"
    4) "b"
    5) "e"
    #Get the number of elements in the Set collection.
    redis 127.0.0.1:6379> scard myset
    (integer) 5

    2. spop/srem/srandmember/smove。
コピーコード コードは以下の通りです。

    #Remove the key for later testing.
    redis 127.0.0.1:6379> del myset
    (integer) 1
    #Prepare test data for the examples that follow.
    redis 127.0.0.1:6379> sadd myset a b c d
    (integer) 4
    # View the location of the member in Set.
    redis 127.0.0.1:6379> smembers myset
    1) "c"
    2) "d"
    3) "a"
    4) "b"
    # From the results, you can see that the command does return a random member.
    redis 127.0.0.1:6379> srandmember myset
    "c"
    The trailing member b in #Set is moved out and returned, and in fact b is not the first or last member inserted previously.
    redis 127.0.0.1:6379> spop myset
    "b"
    #View the membership information for Set after moving out.
    redis 127.0.0.1:6379> smembers myset
    1) "c"
    2) "d"
    3) "a"
    #Remove the members a, d and f from Set, where f does not exist, so only the members a and d are removed, returning 2.
    redis 127.0.0.1:6379> srem myset a d f
    (integer) 2
    # View the output after moving out.
    redis 127.0.0.1:6379> smembers myset
    1) "c"
    #Prepare data for the smove command later.
    redis 127.0.0.1:6379> sadd myset a b
    (integer) 2
    redis 127.0.0.1:6379> sadd myset2 c d
    (integer) 2
    # Move a from myset to myset2, and you can see from the result that the move was successful.
    redis 127.0.0.1:6379> smove myset myset2 a
    (integer) 1
    # Move a from myset to myset2 again. Since a is no longer a member of myset at this point, the move fails and returns 0.
    redis 127.0.0.1:6379> smove myset myset2 a
    (integer) 0
    # Check the members of myset and myset2 separately to confirm that the move actually succeeded.
    redis 127.0.0.1:6379> smembers myset
    1) "b"
    redis 127.0.0.1:6379> smembers myset2
    1) "c"
    2) "d"
    3) "a"

   3. sdiff/SDIFFSTORE/SINTER/SINTERSTORE。
コピーコード コードは以下の通りです。

    #Prepare the test data for the commands that follow.
    redis 127.0.0.1:6379> sadd myset a b c d
    (integer) 4
    redis 127.0.0.1:6379> sadd myset2 c
    (integer) 1
    redis 127.0.0.1:6379> sadd myset3 a c e
    (integer) 3
    #myset is compared to myset2, and the members a, b, and d are the difference members between the two. Then use this result to continue the difference comparison with myset3, where b and d are members that do not exist in myset3.
    redis 127.0.0.1:6379> sdiff myset myset2 myset3
    1) "d"
    2) "b"
    # Differentiated members of the 3 collections exist in the diffkey associated Set, and return the number of members inserted.
    redis 127.0.0.1:6379> sdiffstore diffkey myset myset2 myset3
    (integer) 2
    # Check out the results of the sdiffstore operation.
    redis 127.0.0.1:6379> smembers diffkey
    1) "d"
    2) "b"
    # As you can see from the data prepared earlier, the only member intersection of these three Sets is c.
    redis 127.0.0.1:6379> sinter myset myset2 myset3
    1) "c"
    # Store the intersection members of the 3 sets into the Set associated with the interkey and return the number of intersection members.
    redis 127.0.0.1:6379> sinterstore interkey myset myset2 myset3
    (integer) 1
    # Check out the results of the sinterstore operation.
    redis 127.0.0.1:6379> smembers interkey
    1) "c"
    #Get the concatenation of the members of the 3 sets.   
    redis 127.0.0.1:6379> sunion myset myset2 myset3
    1) "b"
    2) "c"
    3) "d"
    4) "e"
    5) "a"
    # Store the concatenation of the members of the 3 collections into the set associated with unionkey and return the number of concatenated members.
    redis 127.0.0.1:6379> sunionstore unionkey myset myset2 myset3
    (integer) 5
    # Check out the results of the suiionstore operation.
    redis 127.0.0.1:6379> smembers unionkey
    1) "b"
    2) "c"
    3) "d"
    4) "e"
    5) "a"

IV. 適用範囲

      1). RedisのSetデータ型を使って、あるブログにアクセスした際のユニークなIPアドレス情報などを記録しておくことができます。このシナリオでは、ブログにアクセスがあるたびに訪問者のIPをRedisに格納するだけで、Setデータ型が自動的にIPアドレスの一意性を保証します。
      2). Set型のサーバーサイド集計操作の容易さと効率性を活用し、データオブジェクト間の連想関係を維持するために使用することができます。たとえば、ある電子機器を購入したすべての顧客のIDが指定されたSetに格納され、別の電子機器を購入した顧客のIDが別のSetに格納されている場合、どの顧客が両方の商品を同時に購入したかを取得したい場合、Setの交点コマンドを最大限に活用して、便利で効率的な操作を実現することができる。