【プライベートブロックチェーンが未来を作る】ワールドステートのデータ設計
ブロックチェーンを使ったアプリケーション開発で、エンジニアが特に意識しなければならないのが、ワールドステートの設計だ。
ブロックチェーン方式でのデータ記録部分は、ブロックチェーンプラットフォームによって自動的に行われるため、特段意識することはない。
今回は、ワールドステートの設計方法について書いてみようと思う。
アプリケーションの品質の良し悪しは、データ設計で決まると言っても過言ではない。
データ結合が難しい
ワールドステートと言っても、実態はLevelDBやCouchDBなど、いわゆるNoSQLと呼ばれるデータベースだ。
NoSQLを使う場合、データを結合することが難しいという事実を頭に入れておいたほうがいい。特にRDBに慣れ親しんだエンジニアは、従来の感覚で設計すると実装が複雑になるので注意が必要だ。
アプリケーションを作るとき、エンジニアは「データをどのように保存しておくか」を考える。データをきれいに確実に保存することがエンジニアの腕の見せどころだったりする。
基本は、「データのまとまりを定義して、分離して保存すること」。
人間が認識しているモノや事象を、まとまりを意識しながら細分化し、必要に応じてつなぐ。これが多くのエンジニアが無意識レベルで行っている思考プロセスだ。
会社の人事データを管理するシステムを例に、ざっくり説明する。
社員情報は、「個人情報」と「所属情報」という2つのまとまりに分けることができる。分けたうえで、個人情報としては氏名、性別、年齢、住所を管理し、所属情報としては部署名、配属日を管理する。
これだけでは、誰がどの部署に所属しているかが分からなくなるので、社員番号のようなIDをつけてデータを結合する。
ワールドステート設計で難しいのは、このデータ結合である。
データ結合が難しいゆえに、データを分離することが難しくなる。
CouchDBにはJOIN句が存在しない。そのためデータ結合はデータベースの外で行わなければならない。
分離されたデータを結合しようとすると、まず、起点となるデータを取り出し、そこに含まれるIDをもとに別のデータを抽出するという2ステップが必要になり、処理性能が落ちやすくなる。
データ管理のしやすさと検索性能はトレードオフ
一般的に、RDBのデータモデリングはデータ構造駆動であると言われる。
まず「データのまとまりを定義して、分離して保存する」という設計を行い、その制約のなかで必要となるデータをかき集める。
これを実現するために、エンジニアは「正規化」と呼ばれる手法を駆使して、データを設計していく。
対して、NoSQLはクエリ駆動である。
「どのようなビューでデータを参照したいか」を洗い出して、それをスムーズに実現するためのデータ構造を模索する。
データ管理上、圧倒的に楽なのは「データ構造駆動」である。
正規化によってデータの配置場所が明確になるため、データが散在することを防ぐことができるからだ。
クエリ駆動設計ではデータのまとまりの概念がその都度変わるという特徴がある。
売上成績を見る場合、「社員情報」と「セールス情報」が一つのまとまりとして認識される。
人事情報を見る場合、「社員情報」と「所属情報」が一つのまとまりとして認識される。
NoSQLはデータ結合が苦手であるため、検索性能を向上させるための策として社員情報を冗長化して持たせたりする。
データ管理のしやすさと、検索性能はトレードオフの関係にある。
データ構造駆動設計では、データを管理しやすくなるが、複数箇所からデータをかき集めて結合するため検索性能が落ちる。
クエリ駆動設計では、データ参照に特化してデータ構造を定義するため検索性能は向上するが、複数ヶ所に同じデータを保持するため管理が難しくなる。
ワールドステートの設計でも、このトレードオフをちょうどよいところでバランスさせなければならない。
僕は、データ駆動設計とクエリ駆動設計を組み合わせて設計するのがよいと考えている。
具体的には、まずは第三正規化まで正規化を行い、データのまとまりを整理する。
次に、各項目ごとに参照頻度を検討する。
例えば、Aというデータを参照する際に、高頻度でBというデータを一緒に参照しているなと当たりをつける。
そこまで当たりをつけたら、Bの情報をAのデータの中にコピーして、意図的に冗長化を崩していく。
このように設計することで、データ管理のしやすさと、検索性能をバランスさせることができる。
NoSQLを使ったワールドステート設計において、キレイに作ることにこだわり過ぎてはいけない。
データのまとまりはある程度担保したうえで、ハイパフォーマンスで動かすための努力が必要だ。
余談だが、データ結合が難しいという特徴は、ブロックチェーンを採用するユースケースにも影響する。
多種多様なビューで、ブロックチェーンに格納したデータを集計するようなユースケースでは、ブロックチェーンを採用しないほうがいいと思う。