Open3

Redis の List型 と Set型の違い

tamaco489tamaco489

List型とSet型の違い

比較項目 List型 Set型
順序 あり(インデックスアクセス可能) なし
重複 OK NG(重複は追加されない)
取り出し方法 LRANGE, LPOP, RPOP SMEMBERS, SPOPなど
要素の検索 インデックス or 全走査 高速(内部はハッシュ構造)
集合演算 不可 可(SINTER, SUNION, etc)
主な用途 キュー、履歴、順序が重要なリスト 一意な集合、存在チェック


ユースケースに応じてどちらを選択したら良いのか

要件 おすすめ
順序が必要 List
重複を許可したい List
一意な要素の集合が欲しい Set
順序は不要、検索や集合演算が重要 Set
tamaco489tamaco489

List型の場合

# 初期データを投入
127.0.0.1:6379> RPUSH user:{10065807}:articles 300001 300002 300003
(integer) 3
127.0.0.1:6379> LRANGE user:{10065807}:articles 0 -1
1) "300001"
2) "300002"
3) "300003"
127.0.0.1:6379> LLEN user:{10065807}:articles
(integer) 3

# 重複する値として 300003 を再度投入
127.0.0.1:6379> RPUSH user:{10065807}:articles 300003
(integer) 4
127.0.0.1:6379> LRANGE user:{10065807}:articles 0 -1
1) "300001"
2) "300002"
3) "300003"
4) "300003"
127.0.0.1:6379> LLEN user:{10065807}:articles
(integer) 4

→重複制御が行われていないため同じ値を投入できてしまう。

補足事項: LREM を使ってから RPUSH することで重複のないデータを登録できるようになる
# 300003 が存在している場合は削除する
127.0.0.1:6379> LREM user:{10065807}:articles 0 300003
(integer) 2

# 再度 300003 を投入
127.0.0.1:6379> RPUSH user:{10065807}:articles 300003
(integer) 3

# 重複のないデータを投入できている
127.0.0.1:6379> LRANGE user:{10065807}:articles 0 -1
1) "300001"
2) "300002"
3) "300003"
127.0.0.1:6379> LLEN user:{10065807}:articles
(integer) 3


指定した値に重複がない場合は特に何も起こらない

# 900003 はリストの中に存在しないので特に何も起こらない
127.0.0.1:6379> LREM user:{10065807}:articles 0 900003
(integer) 0
127.0.0.1:6379> LRANGE user:{10065807}:articles 0 -1
1) "300001"
2) "300002"
3) "300003"
127.0.0.1:6379> LLEN user:{10065807}:articles
(integer) 3


指定した値が複数含まれれている場合も同様の挙動

# 300003 がすでに3つ存在
127.0.0.1:6379> LRANGE user:{10065807}:articles 0 -1
1) "300001"
2) "300002"
3) "300003"
4) "300003"
5) "300003"
127.0.0.1:6379> LLEN user:{10065807}:articles
(integer) 5

# 300003 をリストの中から削除
127.0.0.1:6379> LREM user:{10065807}:articles 0 300003
(integer) 3

# 300003 3つ全て消去されていることを確認
127.0.0.1:6379> LRANGE user:{10065807}:articles 0 -1
1) "300001"
2) "300002"
127.0.0.1:6379> LLEN user:{10065807}:articles
(integer) 2
tamaco489tamaco489

Set型の場合

# 初期データを投入
127.0.0.1:6379> SADD user:{10065807}:articles 300001 300002 300003
(integer) 3

127.0.0.1:6379> SMEMBERS user:{10065807}:articles
1) "300001"
2) "300002"
3) "300003"

127.0.0.1:6379> SCARD user:{10065807}:articles
(integer) 3

# 重複する値として 300003 を再度投入
127.0.0.1:6379> SADD user:{10065807}:articles 300003
(integer) 0

127.0.0.1:6379> SMEMBERS user:{10065807}:articles
1) "300001"
2) "300002"
3) "300003"

127.0.0.1:6379> SCARD user:{10065807}:articles
(integer) 3

→重複制御が行われているため投入前後で値が変わらない。