SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

分散DBMS「Mnesia」の並列処理

Erlangの並列処理に関する側面を解説

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード サンプルコード (1.1 KB)

ダーティな操作

 より高速にデータにアクセスしなければならない場合のために、Mnesiaには、トランザクションのオーバーヘッドなしにテーブルを操作する「ダーティな」関数が用意されています。この関数を使用するとパフォーマンスが高まり、Mnesiaは一種のリアルタイムDBMSになります。ただし、トランザクションの原子性と独立性は著しく損なわれます。

 サンプルのtest.erlファイルには、以下の関数が記述されています。

  • op:レコード#1を削除し、レコード#5を挿入するトランザクション関数
  • reverse_op:レコード#5を削除し、レコード#1を挿入するトランザクション関数
  • mop:opとreverse_opを指定の回数実行する
  • dirty_opdirty_reverse_opdirty_mop:上記の関数のダーティバージョン

 まず、Counter = 10000にしてtest:mop(Counter)を実行し、この関数をfirst@charlieノードとsecond@deltaノードで十分な時間動作させます。この関数は両ノードで実行され、一貫性の問題を生じることなく終了しました。同時にthird@nemoでtest:select()を実行すると、3レコードから成るリストが常に返されます。これは、opreverse_opも1回でmnesia:writemnesia:deleteを適用するからです。

 同じtestのダーティバージョンであるtest:dirty_mop(Counter)を両ノード上で同時に実行すると、多数のエラーメッセージが発生します。また、third@nemoでtest:select()を実行すると、2レコードまたは4レコードから成るリストが返される場合もあります。

クエリーリスト内包表記

 Mnesiaにはテーブル内のデータとやり取りするSQL風の言語はありませんが、ErlangのQuery List Comprehensionモジュール(qlc)を使用することで、Erlangをデータベース言語として使用し、データベースに問い合わせることができます。qlcモジュールは、リスト内包表記という強力なErlang構文を利用します。

 数学的集合を定義したい場合は、集合ビルダーの表記法を用います。これは、集合の要素の特性を記述することによって、集合の要素を限定するものです。今度は、この表記法とErlangのリスト内包表記構文がどれくらい似ているかを見てみましょう。

 Aは、10より小さく、かつ2乗しても自身と同じ数になる自然数(N)の集合を表しています。これを数式で表すと次のようになります。

 Erlangでは、lists:seq(0,9)という関数呼び出しで10未満のすべての整数のリストを返すことができるので、以下の構文を使用して上述の要素のリストを取得できます。

1> A = [X || X <- lists:seq(0,9), X == X * X].
[0,1]

 2つの式の類似性は顕著です。リスト内包表記は、リストからリストを作成するツールと考えることもできます。以下に一般的な構文を示します。Expressionは、Qualifier1などの修飾子によって生成およびフィルタされた要素に対して行う一連の演算です。

[Expression || Qualifier1, Qualifier2, ...]

 Mnesiaデータベースに問い合わせるためのインターフェースをqlcがどのように提供しているか理解できたでしょう。ただし、このモジュールを使用する前に、システムのどこにファイル「qlc.hrl」があるかを探し、コードに以下の行を含める必要があります。

-include_lib("/path_to/qlc.hrl" ).

 私のtest.erlでは、関数test:select()はtable1の全レコードからなるリストを返します。以下の行に注意してみると、

Handle = qlc:q([X || X <- mnesia:table(table1)])

 関数qlc:qに渡している引数がリスト内包表記であることに気付くでしょう。このリスト内包表記では、テーブルの内容を返す関数mnesia:tableをジェネレータとしています。関数qlc:qが返したクエリーハンドルは関数qlc:eで評価され、この関数によってすべてのテーブルデータが収集され、リストとして返されます。

QueryList = qlc:e(Handle).

 先に説明した理由から、これらすべての関数がmnesia:transactionの内部で動作することに注意してください。関数test:join()には、テーブルtable1とtable2を結合する簡単な例が含まれています。この部分のクエリーリスト内包表記は次のようになります。

Handle = qlc:q([X#table1.number || X <- mnesia:table(table1),
                                   Y <- mnesia:table(table2),
                                   X#table1.number > 2000,
                                   X#table1.table1_id =:= Y#table2.table2_id
])

 実際のところ、レコードとは、命令(先頭文字がマイナス記号の記述)で宣言された名前付きフィールドから成るタプルです。レコード内のフィールドにアクセスするには、ドット構文を使用します。例えば、X#table1.numberは、指定されたフィールドnumberの値を返します。Xはtable1のレコードとして評価されます。

Mnesiaを探求する

 Mnesiaの重要な機能をいくつか紹介してきましたが、もちろんこれですべてではありません。これまで学習してきたことが読者の好奇心を呼び起こし、Mnesiaについてもっと知りたいと思っていただければ幸いです。Mnesiaの可能性を最大限に引き出すため、ぜひ他の機能もより深く知ってもらいたいと思います。

参考資料

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Roberto Giorgetti(Roberto Giorgetti)

イタリアに拠点を置くITマネージャ、テクニカルライター。主にビジネス分野と工業分野でオープンソースの開発に従事。核工学の学位を持つ。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5014 2010/04/05 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング