連載
» 2008年08月19日 00時00分 公開

memcachedの使い方(2):pgmemcacheからmemcachedのデータを操作する (2/3)

[鈴木啓修,InterDB]

pgmemcacheの応用 —PostgreSQLからmemcachedを使う

 具体例を使ってPostgreSQLからmemcachedを使う方法を説明します。

 下図のようなシステムを構築してみましょう。このシステムはSNSの一部で、ユーザーがWebサーバにアクセスすると自身や友人のプロフィール(ニックネーム、友人数、写真)が複数表示されます。

 アクセスのたびにデータベースのユーザーテーブルを検索するのは効率が悪いので、ユーザーデータの登録や更新など基本的な管理はPostgreSQLで行い、検索はmemcachedに任せる分業方式にします。

図 PostgreSQLとmemcachedの関係(概略) 図 PostgreSQLとmemcachedの関係(概略)

 PostgreSQLのテーブルデータをmemcachedに反映させるにはトリガ機能を使います。トリガ機能とはSQL文が実行されたときにあらかじめ指定した関数を実行する機能です。これを使って、登録や変更があった場合にpgmemcacheの関数でデータを保存・更新・削除するように設定しておけば、PostgreSQLとmemcachedの連携が可能となります。

システム構築

 いよいよシステム構築を開始します。といっても、テーブルを定義してトリガ関数とトリガを1つずつ定義するだけです。

テーブル定義とシステム仕様

 今回のユーザーテーブル定義を示します。サンプルなので必要最小限の項目だけ用意しています。

CREATE TABLE userlist (
  uid int primary key,          /* ユーザID */
  flag boolean DEFAULT true,    /* このユーザデータが有効か無効か */
  name text,                    /* 氏名 */
  nickname text,                /* ニックネーム */
  friends_num int,              /* 友人の数 */
  photo text                    /* 写真 */
  );

 また、今回の仕様として、ユーザーデータの登録はINSERT、変更と退会はUPDATEで行うことにします。

 ユーザーが退会してもすぐにはユーザーテーブルuserlistから削除しません。退会時はflagをfalseにするだけで、後でバッチ処理で削除します。

 memcachedにはuidをキー、nicknameとfriends_numとphotoをカンマ「,」で結合した文字列をデータとして保存することにします。

データ例)
key = '12345'
data = 'GOLGO13,2,gol13.jpg'


トリガ関数の定義

 トリガ関数userlist_op()を定義します。この関数は、テーブルuserlistにINSERTまたはUPDATEが実行された直後に(連鎖的に)実行されます。

01: CREATE FUNCTION userlist_op() RETURNS TRIGGER AS
02: $$
03: DECLARE
04:     data text;
05: BEGIN
06:        data := NEW.nickname || ',' || NEW.friends_num || ',' || NEW.photo;
07:
08:       /* INSERT */
09:       IF TG_OP = 'INSERT' THEN
10:          PERFORM memcache_add(NEW.uid::TEXT, data, INTERVAL '2 days');
11:
12:        /* UPDATE */
13:        ELSIF TG_OP = 'UPDATE' THEN
14:          IF NEW.flag = FALSE  THEN
15:            /* flag = FALSE --> 退会 */
16:           PERFORM memcache_delete(NEW.uid::TEXT);
17:           ELSE
18:            /* flag = TRUE --> 更新 */
19:            PERFORM memcache_replace(NEW.uid::TEXT,  data, INTERVAL '2 days');
20:          END IF;
21:
22:        END IF;
23:
24:        RETURN NULL;
25: END;
26: $$
27: LANGUAGE 'plpgsql';

 6行目で登録するデータを作ります。今回はnicknameとfriends_numとphotoをカンマ「,」区切りで結合するのでこのようになりますが、実運用では適宜システムに合わせてください。

 8〜22行目が処理本体です。INSERT実行時(9〜10行目)とUPDATE実行時(13〜20行目)の2つの場合分けになっています。ここでpgmemcacheの関数が登場します。どんな関数が用意されているかはpgmemcacheの付属文書README.pgmemcacheを参照していただくとして、今回は保存memcache_add()、更新memcache_replace()、削除memcache_delete()のみ使用します。

 10行目はINSERT実行時に行う処理で、関数memcache_add()を実行します。第1引数はキーuid、第2引数はデータ、第3引数はexpire時間で今回は2日間を設定しています。

 14〜20行目はUPDATE実行時に行う処理で、flagがFALSEかTRUEかで処理が異なります。

 flagがFALSEの場合は退会したと判断して、関数memcache_delete()を実行しデータを削除します。flagがTRUEの場合はデータが更新されたと判断して、関数memcache_replace()を実行します。

 最後に、トリガuserlist_trgを設定します。

1:CREATE  TRIGGER userlist_trg
2:    AFTER INSERT OR UPDATE ON  userlist
3:    FOR EACH ROW
4:    EXECUTE PROCEDURE userlist_op();

 このトリガはテーブルuserlistがINSERTかUPDATEされたときのみ実行されるように設定しています(2行目)。DELETE実行時には何もしません。これは今回の仕様を反映したためです。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。