1. 概要:
Redis では、リスト タイプは、挿入順に並べ替えられた文字列のリンク リストです。データ構造内の通常のリンク リストと同様に、その先頭 (左) と末尾 (右) に新しい要素を追加できます。挿入中にキーが存在しない場合、Redis はキーの新しいリンク リストを作成します。 (推奨: redis ビデオ チュートリアル )
逆に、リンクされたリスト内のすべての要素が削除されると、キーもデータベースから削除されます。リストに含めることができる要素の最大数は 4294967295 です。
要素の挿入と削除の効率の観点から、リンク リストの両端で要素を挿入または削除すると、リンク リストに数百万のレコードが格納されている場合でも、これは非常に効率的な操作になります。 . 一定時間で操作を完了することもできます。
ただし、要素の挿入または削除操作がリンク リストの途中で実行されると、非常に非効率になることに注意してください。これは、優れたデータ構造の基盤を持つ開発者にとっては理解するのが難しいことではないと思います。
2. 関連コマンド リスト:
#コマンド プロトタイプ | 時間計算量 | コマンドの説明 | 戻り値 |
LPUSH キー値 [値 ...] | O(1) | パラメータで指定されたすべての値を、指定されたキーに関連付けられたリスト値のヘッダーに挿入します。キーが存在しない場合、このコマンドは挿入前にキーに関連付けられた空のリンク リストを作成し、リンク リストの先頭からデータを挿入します。キーの値がリンク リスト タイプでない場合、このコマンドは関連するエラー情報を返します。 | 挿入後のリンク リスト内の要素の数。 |
LPUSHX キーの値 | O(1) | パラメータで指定した Key が存在する場合のみ、コマンドが関連付けられます。リスト値の値がパラメータで指定された値に挿入されます。それ以外の場合、操作は行われません。 | 挿入後のリンク リスト内の要素の数。 |
LRANGE キー start stop | O(S N) | 時間計算量の S は start パラメータで表されるオフセットであり、N は開始パラメータを表します。要素量。このコマンドのパラメータ start と end はどちらも 0 から始まります。つまり、0 はリンク リストの先頭 (左端) の最初の要素を表します。 start の値は負の値にすることもできます。-1 はリンクされたリストの最後の要素、つまり末尾の要素を表し、-2 は最後から 2 番目の要素を表し、以下同様になります。このコマンドで要素を取得すると、開始位置と終了位置の要素も取り出されます。 start の値がリンク リスト内の要素の数より大きい場合、空のリンク リストが返されます。 end の値が要素の数より大きい場合、このコマンドは、start から始まるリンク リスト内の残りの要素をすべて取得します (start を含む)。 | 指定された範囲内の要素のリストを返します。 |
LPOP key | O(1) | 指定されたキーに関連付けられたリンク リストの最初の要素を返し、ポップアップします。 head 要素。キーが存在しない場合は nil を返します。 | リンクされたリストの先頭の要素。 |
LLEN key | O(1) | 指定されたキーに関連付けられたリンク リスト内の要素の数を返します。存在する場合は 0 を返します。キーに関連付けられた値のタイプがリンク リストでない場合は、関連するエラー情報が返されます。 | リンクされたリスト内の要素の数。時間計算量における |
LREM キー カウント値 | O(N) | N は、リンク リスト内の要素の数を表します。指定されたキーに関連付けられたリンク リストで、値が value に等しい最初の count 要素を削除します。 count が 0 より大きい場合は、最初から最後まで走査して削除し、count が 0 未満の場合は、端から先頭まで走査して削除します。 count が 0 に等しい場合、リンクされたリスト内の value に等しい要素をすべて削除します。指定したKeyが存在しない場合は、直接0を返します。 | 削除された要素の数を返します。 |
LSET キー インデックス値 | O(N) | N (時間計算量) は、リンク リスト内の要素の数を表します。ただし、先頭要素または末尾要素を設定する場合の時間計算量は O(1) です。リンクされたリスト内の指定された位置の値を新しい値に設定します。0 は最初の要素、つまり先頭要素を表し、-1 は末尾要素を表します。インデックス値 Index がリンク リスト内の要素の数を超える場合、このコマンドは関連するエラー情報を返します。 |
LINDEX キー インデックス |
O(N) |
N の時間計算量は、検索時に走査する必要があることを意味しますelement 要素の数。先頭要素または末尾要素の場合、その時間計算量は O(1) です。このコマンドは、リンク リスト内の指定された位置 (インデックス) にある要素を返します。インデックスは 0 から始まり、先頭要素を意味します。インデックスが -1 の場合は末尾要素を意味します。キーがリンク リストに関連付けられていない場合、このコマンドは関連するエラー情報を返します。 |
要求された要素を返すか、インデックスが範囲外の場合は nil を返します。 |
LTRIM キー start stop |
O(N) |
N は削除された要素の数を表します。このコマンドは、指定された範囲内の要素のみを保持するため、リンク内の要素の数は比較的一定に保たれます。 start パラメータと stop パラメータはどちらも 0 ベースで、0 はヘッダー要素を示します。他のコマンドと同様に、start と stop には負の値を指定することもでき、-1 は末尾要素を表します。 start がリンク リストの終わりより大きい場合、または start が stop より大きい場合、このコマンドはエラーを報告しませんが、空のリンク リストを返し、キーも削除されます。 stop が要素の数より大きい場合、start から残っているすべての要素が保持されます。 |
|
LINSERT キー BEFORE|AFTER ピボット値 |
O(N) |
時間計算量の場合、N は検索時を意味します。要素がピボットする前に走査する必要がある要素の数。これは、ピボットがリンク リストの先頭または末尾にある場合、このコマンドの時間計算量は O(1) であることを意味します。このコマンドの機能は、ピボット要素の前後のパラメータに要素値を挿入することです。キーが存在しない場合、このコマンドは何も行いません。 Key に関連付けられた値の型がリンク リストではない場合、関連するエラー情報が返されます。 |
挿入が成功した後のリンク リスト内の要素の数。ピボットが見つからない場合は -1 が返されます。キーが存在しない場合は 0 が返されます。 |
RPUSH キー値 [値 ...] |
O(1) |
に関連付けられたリスト値の末尾にパラメータを挿入します。指定されたキーすべての値が指定されます。キーが存在しない場合、このコマンドは、挿入前にキーに関連付けられた空のリンク リストを作成し、リンク リストの末尾からデータを挿入します。キーの値がリンク リスト タイプでない場合、このコマンドは関連するエラー情報を返します。 |
挿入後のリンク リスト内の要素の数。 |
RPUSHX キーの値 |
O(1) |
パラメータで指定された Key が存在する場合のみ、コマンドがそれに関連付けられます。パラメータで指定された値はリスト値の最後に挿入されます。それ以外の場合、操作は行われません。 |
挿入後のリンク リスト内の要素の数。 |
RPOP key | O(1) | 指定されたキーに関連付けられたリンク リストの最後の要素を返し、ポップアップします。尾部要素。キーが存在しない場合は nil を返します。 | リンクされたリストの最後の要素。 |
RPOPLPUSH ソース宛先 | O(1) | ソース キーに関連付けられたリンク リストの末尾から要素をアトミックにポップし、再度ポップアップします。 要素は、宛先キーに関連付けられたリンク リストの先頭に挿入されます。ソースキーが存在しない場合、コマンドは nil を返し、他の操作は実行されません。ソースと宛先が同じキーの場合、関連付けられたリンク リストの末尾要素をリンク リストの先頭にアトミックに移動することと同じです。 | ポップおよび挿入された要素を返します。 |
3. コマンド例:
1、LPUSH/LPUSHX/LRANGE:
/> redis-cli #在Shell提示符下启动redis客户端工具。
redis 127.0.0.1:6379> del mykey
(integer) 1
#mykey键并不存在,该命令会创建该键及与其关联的List,之后在将参数中的values从左到右依次插入。
redis 127.0.0.1:6379> lpush mykey a b c d
(integer) 4
#取从位置0开始到位置2结束的3个元素。
redis 127.0.0.1:6379> lrange mykey 0 2
1) "d"
2) "c"
3) "b"
#取链表中的全部元素,其中0表示第一个元素,-1表示最后一个元素。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
#mykey2键此时并不存在,因此该命令将不会进行任何操作,其返回值为0。
redis 127.0.0.1:6379> lpushx mykey2 e
(integer) 0
#可以看到mykey2没有关联任何List Value。
redis 127.0.0.1:6379> lrange mykey2 0 -1
(empty list or set)
#mykey键此时已经存在,所以该命令插入成功,并返回链表中当前元素的数量。
redis 127.0.0.1:6379> lpushx mykey e
(integer) 5
#获取该键的List Value的头部元素。
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"
#在执行lpop命令两次后,链表头部的两个元素已经被弹出,此时链表中元素的数量是2
redis 127.0.0.1:6379> llen mykey
(integer) 2
ログイン後にコピー
3、LREM/LSET/LINDEX/LTRIM:
#为后面的示例准备测试数据。
redis 127.0.0.1:6379> lpush mykey a b c d a c
(integer) 6
#从头部(left)向尾部(right)变量链表,删除2个值等于a的元素,返回值为实际删除的数量。
redis 127.0.0.1:6379> lrem mykey 2 a
(integer) 2
#看出删除后链表中的全部元素。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "c"
2) "d"
3) "c"
4) "b"
#获取索引值为1(头部的第二个元素)的元素值。
redis 127.0.0.1:6379> lindex mykey 1
"d"
#将索引值为1(头部的第二个元素)的元素值设置为新值e。
redis 127.0.0.1:6379> lset mykey 1 e
OK
#查看是否设置成功。
redis 127.0.0.1:6379> lindex mykey 1
"e"
#索引值6超过了链表中元素的数量,该命令返回nil。
redis 127.0.0.1:6379> lindex mykey 6
(nil)
#设置的索引值6超过了链表中元素的数量,设置失败,该命令返回错误信息。
redis 127.0.0.1:6379> lset mykey 6 hh
(error) ERR index out of range
#仅保留索引值0到2之间的3个元素,注意第0个和第2个元素均被保留。
redis 127.0.0.1:6379> ltrim mykey 0 2
OK
#查看trim后的结果。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "c"
2) "e"
3) "c"
ログイン後にコピー
4、LINSERT:
#删除该键便于后面的测试。
redis 127.0.0.1:6379> del mykey
(integer) 1
#为后面的示例准备测试数据。
redis 127.0.0.1:6379> lpush mykey a b c d e
(integer) 5
#在a的前面插入新元素a1。
redis 127.0.0.1:6379> linsert mykey before a a1
(integer) 6
#查看是否插入成功,从结果看已经插入。注意lindex的index值是0-based。
redis 127.0.0.1:6379> lindex mykey 0
"e"
#在e的后面插入新元素e2,从返回结果看已经插入成功。
redis 127.0.0.1:6379> linsert mykey after e e2
(integer) 7
#再次查看是否插入成功。
redis 127.0.0.1:6379> lindex mykey 1
"e2"
#在不存在的元素之前或之后插入新元素,该命令操作失败,并返回-1。
redis 127.0.0.1:6379> linsert mykey after k a
(integer) -1
#为不存在的Key插入新元素,该命令操作失败,返回0。
redis 127.0.0.1:6379> linsert mykey1 after a a2
(integer) 0
5. RPUSH/RPUSHX/RPOP/RPOPLPUSH:
#删除该键,以便于后面的测试。
redis 127.0.0.1:6379> del mykey
(integer) 1
#从链表的尾部插入参数中给出的values,插入顺序是从左到右依次插入。
redis 127.0.0.1:6379> rpush mykey a b c d
(integer) 4
#通过lrange的可以获悉rpush在插入多值时的插入顺序。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
#该键已经存在并且包含4个元素,rpushx命令将执行成功,并将元素e插入到链表的尾部。
redis 127.0.0.1:6379> rpushx mykey e
(integer) 5
#通过lindex命令可以看出之前的rpushx命令确实执行成功,因为索引值为4的元素已经是新元素了。
redis 127.0.0.1:6379> lindex mykey 4
"e"
#由于mykey2键并不存在,因此该命令不会插入数据,其返回值为0。
redis 127.0.0.1:6379> rpushx mykey2 e
(integer) 0
#在执行rpoplpush命令前,先看一下mykey中链表的元素有哪些,注意他们的位置关系。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
#将mykey的尾部元素e弹出,同时再插入到mykey2的头部(原子性的完成这两步操作)。
redis 127.0.0.1:6379> rpoplpush mykey mykey2
"e"
#通过lrange命令查看mykey在弹出尾部元素后的结果。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
#通过lrange命令查看mykey2在插入元素后的结果。
redis 127.0.0.1:6379> lrange mykey2 0 -1
1) "e"
#将source和destination设为同一键,将mykey中的尾部元素移到其头部。
redis 127.0.0.1:6379> rpoplpush mykey mykey
"d"
#查看移动结果。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "d"
2) "a"
3) "b"
4) "c"
ログイン後にコピー
4. リンク リスト構造に関するヒント:
リンク リスト構造の値については、Redis の公式ドキュメント (RPOPLPUSH コマンドなど) でいくつかの実践的なヒントが提供されています。
Redis リンク リストは、複数のプログラム間のメッセージ交換を完了するためにメッセージ キュー サービスでよく使用されます。
アプリケーションがリンク リストに新しい要素を追加するために LPUSH 操作を実行しているとします。通常、このようなプログラムを「プロデューサー」と呼びますが、別のアプリケーションがリンク リストに新しい要素を追加するために RPOP 操作を実行しています。プログラムから要素を削除する場合、そのようなプログラムを「コンシューマ」と呼びます。
このとき、メッセージ要素が取り出されて正常に処理されなかったため、メッセージ要素を取り出した直後にコンシューマプログラムがクラッシュした場合、メッセージは失われたと考えられます。業務データの消失や業務状態の不整合が発生する。
ただし、RPOPLPUSH コマンドを使用すると、コンシューマ プログラムはメイン メッセージ キューからメッセージを削除し、バックアップ キューに挿入します。コンシューマ プログラムがメッセージを完了するまで、バックアップ キューからメッセージは削除されません。通常の処理ロジックで削除します。
同時に、デーモン プロセスも提供できます。バックアップ キュー内のメッセージの有効期限が切れていることが判明した場合、メッセージをメイン メッセージ キューに戻すことができるため、他のコンシューマ プログラムは処理を続行できます。 。
redis の詳細については、redis 入門チュートリアル 列に注目してください。
以上がRedisのリストタイプと関連コマンドの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。