RDBの機能をNoSQLで実現する(2)RDB開発者におくるNoSQLの常識(4)(2/3 ページ)

» 2011年06月16日 00時00分 公開
[渡辺俊史株式会社システムインテグレータ]

用途によっては別のキャッシュテーブルに

 ここまでの手順で、KVSにカスタマーレビューのデータを格納するためのデータ構造を用意できました。ただ、KVSを使用する上でもう一歩踏み込んで考えておきたいポイントがあります。今回はレビューを格納するデータ構造として図2のようなモデルを考えました。しかし、実際には「書籍紹介ページのレビュー一覧」で表示するレビューの集まりは必ず、1冊の本に関するレビューのはずですから、何度も同じ項目を格納するのは冗長です。

 KVSでキャッシュテーブルを作るということはSQLのクエリやビューとは異なり、物理的なストレージを消費します。最近はストレージ容量のコストが問題になることは少なくなりましたが、高速にデータを読み書きするにはなるべく無駄なデータを少なくしたほうがよいでしょう。書籍タイトルは別の方法で取得することにして、図3のようにデータ構造から排除してしまうのがよいかもしれません。

図3 KVSにカスタマーレビューのデータを格納するためのデータ構造 図3 KVSにカスタマーレビューのデータを格納するためのデータ構造

 「本のレビュー」というデータの使い道はこれだけではありません。カスタマーレビューの数が増えてくると、だんだんレビューの質にばらつきが出てくるので、今度は「有用なレビューを書いてくれる○○さんのレビューを読みたい」という利用シナリオが浮かび上がります。ユーザーのニーズに対応するため、この書籍サイトに対し「この人のレビュー一覧」ページを追加する、という拡張が考えられます。

 図2をもう一度見てみましょう。先ほどのケースでは「ある書籍に対応するレビューの一覧を表示する」というシナリオから、キー情報の生成ルールを[書籍ID+投稿日(降順)]のように定めました。

 しかし、今度のケースでは「あるレビュアーが書いたレビューの一覧を表示する」という機能を作るので、できればキー情報をレビュアーの会員IDを使ったものに入れ替えて、取得パフォーマンスを稼ぎたいところです。また、今度はページ内に表示するレビュアーが必ず1人になりますから、レビュアーのハンドルネームをくり返し保持するのは無駄になってしまいます。反対に、書籍のタイトルはそれぞれ異なる情報になるので、今度は必要な項目になります。「この人のレビュー一覧」ページに最適化して直したKVSキャッシュテーブルのデータ構造は図4のようになります。

図4 レビュアー別にレビューを格納するためのデータ構造 図4 レビュアー別にレビューを格納するためのデータ構造

 RDBMSではデータの物理的な格納場所や並び順などはユーザーからは見えません。利用シナリオの違いはSQLでSELECT句に並べる項目の違いでしかありませんでした。しかし、KVS型のNoSQLデータベースにテーブル構造を移行するときは、データの格納順序など物理的な制約も考慮する必要があります。

 同じ書籍レビューのデータであっても、利用シナリオによっては読み出し用のキャッシュテーブルが複数の形に分かれることもあるのです。第2回で「分散キャッシュは目的にあわせて作る」と説明したのはこのためです。NoSQLデータベースの設計では、論理的なデータ構造だけでなく、物理制約やユースケースにも気を配ってデータ構造を考えることが重要なのです。

集計結果の取得も事前のキャッシュ生成で対応

 「テーブル結合」の次は「集計処理」について考えましょう。RDBMSでは、SQLを使うことで正規化されたテーブルに対し「選択」「射影」「結合」といった関係演算を実行して結果セットを取り出せます。RDBMSには他にも、複数の値の集まりを計算し1つの値として返す「集計関数」を利用してデータを加工する機能があります。

 例えば、図5のようなテーブルに対しSELECT SUM (販売額) FROM 売上というSELECT文を実行することで、RDBMSは売上テーブルにある全ての販売額列の値を合計した結果を返します。また、SUM、COUNT、MIN、MAXなどの集計関数をGROUP BY句と併用することで、「月別の販売額」「年別の販売額」のように集計結果をグループ分けすることもできます。SQLの集計機能については概要の紹介にとどめますが、SQLによるデータ集計機能はRDBMSの大きな魅力の1つです。もしSQLが単に正規化されたデータの組み合わせを取得するだけの言語であったなら、RDBMSは今日のように広く普及することもなかったでしょう。

図5 売上テーブルを集計し、合計金額を計算 図5 売上テーブルを集計し、合計金額を計算

 「大量のデータを集計して、結果を素早く取得する」という機能は、データベースの役割として当然のようにも思えますが、実はこれもNoSQLデータベースでは実現の難しい機能です。NoSQLデータベースは、データを読み取るタイミングで結果セットを動的に生成しないため、対象データを集計した計算結果を返すことができないからです。NoSQLデータベースで集計処理の結果を取得したい場合もテーブル結合のケースと同じように、キャッシュテーブルを作って事前に計算結果を入れておくことで対応します。先ほどの例で考えると、SELECT文の結果として返される形で、キャッシュテーブルを作成するわけです。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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