簡単にRedisデータベースのキーのデザインを話します.
6331 ワード
原文の住所:http://www.hoterran.info/redis_kv_design
豊富なデータ構造は、redisの設計を非常に興味深いものにしています.関係型データベースのように、DEVとDBAは深いコミュニケーションが必要です.reviewの各行のsql文もmemcachedのようにDBAの参加は必要ありません.redisのDBAはデータ構造に詳しい必要があり、使用シーンを知ることができます.
以下にいくつかのよくあるkvデータベースの例を挙げてキーパッドのデザインについて話します.そして関係型データベースと比較して、関係型の不足点を発見します.
ユーザ登録システム
ユーザー登録情報を記録するシステムです.業務を簡略化して、表だけを残します.
関係データベースの設計
REDISの設計
関係型データをKVデータベースに変換する方法は以下の通りです.
key表名:メインキー値:列名
value列の値
普通はコロンを使ってセパレータをするのが無文の決まりです.たとえば、php-admin for redisシステムでは、デフォルトではコロンで分割されますので、アメリカ:1 user:2などのkeyはグループに分かれます.以上の関係データをkvデータに変換して下記のように記録します.
一般ユーザーは自分のIDを知ることができないので、自分のユーザー名だけを知っています.だから、nameからidまでのマッピング関係が必要です.ここのデザインは上のものと違います.
以下のような需要があると仮定して、最近ログインしたN人のユーザを検索する.開発者は見てみます.やはり簡単です.一つのsqlで解決します.
二日間を過ぎて、もう一つ必要があります.登録回数が一番多い人は誰ですか?同じ関係型はどうなりますか?DEVは簡単です
関係型データベースのデータ保存の不活発さは問題の元です.データは一つの保存方法しかありません.つまり行ごとに並べられた積載表です.統一されたデータ構造は、インデックスを使ってsqlのアクセス経路を変えて、ある列に素早くアクセスしなければならないことを意味します.アクセス経路の増加は統計情報を使ってサポートしなければならないことを意味します.
インデックスがなくて、統計計画がなくて、実行計画がなくて、これはkvデータベースです.
レディスでは以上の需要をどう満たすべきですか?最新のN本のデータを求める需要に対して、チェーンの後進の特徴はとても適しています.私達は上の登録コードの後にコードを追加して、登録のリンク表を維持して、彼の長さを制御して、中に永遠に保存するのは一番近いN個の登録ユーザーです.
TAGシステム
(インターネットの応用の中で特に多く見られますが、伝統的な関係型データベースで設計するとちょっと違っています.私たちは本の例を探して、レディスのこの方面の優勢を見てみます.
関係データベースの設計
二枚の表、一枚のbookの明細、一枚の(表)は、一冊の(一冊の)本が複数存在することを表しています.
関係型のデータは実はこれらの集合操作にあまり適していません.
REDISの設計
まずbookのデータは必ず保存します.上記と同じです.
上記の2つの例から、いくつかのシーンでは、関係型データベースはあまり適切ではないことが分かります.必要なシステムを満たすために設計できるかもしれませんが、いつも変な感じがします.
特にシステムにログインするという例は、頻繁に業務のためのインデックスを作成します.複雑なシステムにおいて、ddl(インデックス作成)は実行計画を変更する可能性がある.他のsqlは異なる実行計画を採用して、業務の複雑な古いシステムを招いて、この問題は予測しにくいので、sql千奇百怪.DBAにこのシステムのsqlを全部知ってもらうのは難しいです.この問題はoracleの中で特に深刻で、DBAごとにぶつかったことがあると思います.MySQLというシステムに対して、ddlは不便です.大きい時計に出会って、DBAは明け方に起きて業務の低いピークの期限で操作して、この事は私は少なくしたことがありません.このような需要はredisの中に置いてとても良く処理して、DBAは容量だけを予見してすぐできます.
未来のOLT Pシステムはkvと関係型の緊密な結合であるべきである.
豊富なデータ構造は、redisの設計を非常に興味深いものにしています.関係型データベースのように、DEVとDBAは深いコミュニケーションが必要です.reviewの各行のsql文もmemcachedのようにDBAの参加は必要ありません.redisのDBAはデータ構造に詳しい必要があり、使用シーンを知ることができます.
以下にいくつかのよくあるkvデータベースの例を挙げてキーパッドのデザインについて話します.そして関係型データベースと比較して、関係型の不足点を発見します.
ユーザ登録システム
ユーザー登録情報を記録するシステムです.業務を簡略化して、表だけを残します.
関係データベースの設計
mysql> select * from login;
+---------+----------------+-------------+---------------------+
| user_id | name | login_times | last_login_time |
+---------+----------------+-------------+---------------------+
| 1 | ken thompson | 5 | 2011-01-01 00:00:00 |
| 2 | dennis ritchie | 1 | 2011-02-01 00:00:00 |
| 3 | Joe Armstrong | 2 | 2011-03-01 00:00:00 |
+---------+----------------+-------------+---------------------+
アメリカ.idテーブルのメインキー、nameはユーザー名、login_を表します.timesは当該ユーザのログイン回数を表し、ユーザー登録ごとにlogin_timesは自然に増えますが、last_ロゴタイムを現在の時間に更新します.REDISの設計
関係型データをKVデータベースに変換する方法は以下の通りです.
key表名:メインキー値:列名
value列の値
普通はコロンを使ってセパレータをするのが無文の決まりです.たとえば、php-admin for redisシステムでは、デフォルトではコロンで分割されますので、アメリカ:1 user:2などのkeyはグループに分かれます.以上の関係データをkvデータに変換して下記のように記録します.
Set login:1:login_times 5
Set login:2:login_times 1
Set login:3:login_times 2
Set login:1:last_login_time 2011-1-1
Set login:2:last_login_time 2011-2-1
Set login:3:last_login_time 2011-3-1
set login:1:name ”ken thompson“
set login:2:name “dennis ritchie”
set login:3:name ”Joe Armstrong“
このように、マスターキーが知られている場合は、ユーザの登録回数と最終登録時間と名前をget、setによって取得または変更することができる.一般ユーザーは自分のIDを知ることができないので、自分のユーザー名だけを知っています.だから、nameからidまでのマッピング関係が必要です.ここのデザインは上のものと違います.
set "login:ken thompson:id" 1
set "login:dennis ritchie:id" 2
set "login: Joe Armstrong:id" 3
このようにユーザがログインするたびに、業務ロジックは以下の通りであり、rはredisオブジェクトであり、nameはすでに知られているユーザ名である.# id
uid = r.get("login:%s:id" % name)
#
ret = r.incr("login:%s:login_times" % uid)
#
ret = r.set("login:%s:last_login_time" % uid, datetime.datetime.now())
必要があるのは既知のIDだけなら、あるユーザーの最終登録時間を更新したり、取得したりして、ログイン回数、関係型とkvデータベースは何の違いもありません.一つはbtree pkを通して、一つはshを通して、効果はすべてとても良いです.以下のような需要があると仮定して、最近ログインしたN人のユーザを検索する.開発者は見てみます.やはり簡単です.一つのsqlで解決します.
select * from login order by last_login_time desc limit N
DBAは需要を了解した後、今後の表が大きいと考えています.ロゴtimeでインデックスを作ります.実行計画はインデックスleafblockの一番右からN条の記録にアクセスして、またN回表に戻ります.効果はとてもいいです.二日間を過ぎて、もう一つ必要があります.登録回数が一番多い人は誰ですか?同じ関係型はどうなりますか?DEVは簡単です
select * from login order by login_times desc limit N
DBAを見たらまたlogin_timeでインデックスを作成します.ちょっと問題があると思いますか?表にはフィールドごとに素引があります.関係型データベースのデータ保存の不活発さは問題の元です.データは一つの保存方法しかありません.つまり行ごとに並べられた積載表です.統一されたデータ構造は、インデックスを使ってsqlのアクセス経路を変えて、ある列に素早くアクセスしなければならないことを意味します.アクセス経路の増加は統計情報を使ってサポートしなければならないことを意味します.
インデックスがなくて、統計計画がなくて、実行計画がなくて、これはkvデータベースです.
レディスでは以上の需要をどう満たすべきですか?最新のN本のデータを求める需要に対して、チェーンの後進の特徴はとても適しています.私達は上の登録コードの後にコードを追加して、登録のリンク表を維持して、彼の長さを制御して、中に永遠に保存するのは一番近いN個の登録ユーザーです.
#
ret = r.lpush("login:last_login_times", uid)
# N
ret = redis.ltrim("login:last_login_times", 0, N-1)
これは最新の登録者のIDを取得する必要があります.下記のコードで結構です.last_login_list = r.lrange("login:last_login_times", 0, N-1)
また、登録回数が一番多い人は、ランキング、ポイントリストなどの需要に対して、sorted setがとても適しています.私たちはユーザーと登録回数を一つのsorted setにまとめて保存します.zadd login:login_times 5 1
zadd login:login_times 1 2
zadd login:login_times 2 3
このように、あるユーザーが登録したら、もう一つのsorted setを維持します.コードはこのようです.# 1
ret = r.zincrby("login:login_times", 1, uid)
登録回数が一番多いユーザーはどうなりますか?順番を逆順に並べてN番目のユーザーを獲得すればいいです.ret = r.zrevrange("login:login_times", 0, N-1)
DEVは2行のコードを追加する必要があり、DBAはインデックスなどを考慮する必要がないことが分かります.TAGシステム
(インターネットの応用の中で特に多く見られますが、伝統的な関係型データベースで設計するとちょっと違っています.私たちは本の例を探して、レディスのこの方面の優勢を見てみます.
関係データベースの設計
二枚の表、一枚のbookの明細、一枚の(表)は、一冊の(一冊の)本が複数存在することを表しています.
mysql> select * from book;
+------+-------------------------------+----------------+
| id | name | author |
+------+-------------------------------+----------------+
| 1 | The Ruby Programming Language | Mark Pilgrim |
| 1 | Ruby on rail | David Flanagan |
| 1 | Programming Erlang | Joe Armstrong |
+------+-------------------------------+----------------+
mysql> select * from tag;
+---------+---------+
| tagname | book_id |
+---------+---------+
| ruby | 1 |
| ruby | 2 |
| web | 2 |
| erlang | 3 |
+---------+---------+
, ruby web , ?
select b.name, b.author from tag t1, tag t2, book b
where t1.tagname = 'web' and t2.tagname = 'ruby' and t1.book_id = t2.book_id and b.id = t1.book_id
2回関連してからbookと関連しています.このsqlはまだ複雑です.もし要求すればルビーですが、webの本ではないですか?関係型のデータは実はこれらの集合操作にあまり適していません.
REDISの設計
まずbookのデータは必ず保存します.上記と同じです.
set book:1:name ”The Ruby Programming Language”
Set book:2:name ”Ruby on rail”
Set book:3:name ”Programming Erlang”
set book:1:author ”Mark Pilgrim”
Set book:2:author ”David Flanagan”
Set book:3:author ”Joe Armstrong”
私たちは集合を使ってデータを保存します.集合は交差、集合が得意です.sadd tag:ruby 1
sadd tag:ruby 2
sadd tag:web 2
sadd tag:erlang 3
では、ルビーに属してwebの本ですか?inter_list = redis.sinter("tag.web", "tag:ruby")
ルビーに属しますが、webの本ではないですか?inter_list = redis.sdiff("tag.ruby", "tag:web")
ルビーとウェブに属する本の集合?inter_list = redis.sunion("tag.ruby", "tag:web")
簡単ではありません.上記の2つの例から、いくつかのシーンでは、関係型データベースはあまり適切ではないことが分かります.必要なシステムを満たすために設計できるかもしれませんが、いつも変な感じがします.
特にシステムにログインするという例は、頻繁に業務のためのインデックスを作成します.複雑なシステムにおいて、ddl(インデックス作成)は実行計画を変更する可能性がある.他のsqlは異なる実行計画を採用して、業務の複雑な古いシステムを招いて、この問題は予測しにくいので、sql千奇百怪.DBAにこのシステムのsqlを全部知ってもらうのは難しいです.この問題はoracleの中で特に深刻で、DBAごとにぶつかったことがあると思います.MySQLというシステムに対して、ddlは不便です.大きい時計に出会って、DBAは明け方に起きて業務の低いピークの期限で操作して、この事は私は少なくしたことがありません.このような需要はredisの中に置いてとても良く処理して、DBAは容量だけを予見してすぐできます.
未来のOLT Pシステムはkvと関係型の緊密な結合であるべきである.