見出し画像

第3章 ストレージと抽出

要約

OLTPはトランザクション処理に、OLAPは分析処理に特化しています。
インデックスにはハッシュ、SSTable・LSMツリー、Bツリーなどがあり、読み取り速度と書き込み速度のトレードオフがあります。
データウェアハウスではインデックスはあまり機能しません。ストレージでは行ではなく、列指向が使われており効率化を図っています。

前の章

前の章である第2章 データモデルとクエリ言語はこちらです。

OLTPとOLAP

私たちが普段使っているデータベースは2つのやらなければいけないことがあります。
まず1つ目は与えられたデータを保存するということ。
2つ目は保存されたデータを要求されたら返すということです。

上記のようにデータベースには根源的な機能があります。
更にデータベースのストレージエンジンは、トランザクション処理に最適化されたものと分析に最適化されたものがあります。

図3-8(データ指向アプリケーションデザインより)

OLTP(オンライントランザクション処理)

トランザクション処理に最適化されたものをOLTPと呼び、このシステムは通常ユーザが利用することで莫大なリクエストを受け付けたり、それぞれのクエリを処理したりします。

OLAP(オンライン分析処理)

分析処理に最適化されたものをOLAPと呼び、このシステムは主にビジネスアナリストのような職種の人が使用するものになります。OLAPではクエリ一つ一つの負荷は大きく、短時間に大量のレコードスキャンすることが求められるケースがあります。

OLTP(オンライントランザクション処理)

インデックス

データベースから特定のキーの値を効率的に見つけるためには、別のデータ構造(インデックス)が必要になります。 インデックスの概念としてはメタデータを追加で設置し、このメタデータを使うことで必要なデータの場所を知ることができるようになることです。

多くのデータベースでは、インテックスの追加と削除が可能ですがデータベースの内容には影響しません。影響があるのはクエリのパフォーマンスです。
どのような種類のインデックスも、通常は書き込みの速度を低下させます。この理由としてはデータの書き込みのたびにインデックスも更新しなければならないためです。

インデックスはストレージシステムにおける重要なトレードオフになります。読み出しのクエリを高速にしてくれる反面、書き込みを低速にしてしまいます

下記の記事は非常にわかりやすくインデックスについてまとめられています。

インデックスには主に下記のようなものがあります。

  • ハッシュインデックス

  • SSTableとLSMツリー

  • Bツリー

ハッシュインデックス

ハッシュと呼ばれるので、キーバリュー型のインデックスになります。キーバリューストアは、プログラミング言語に見られる辞書型に似ています。

ハッシュインデックスでは、ファイルへの追記だけを行うものと考えてみてください。ディスク領域を使い切る前に録画サイズになったら、ファイルをクローズすることによってログをセグメントに分割することができます。そして、コンパクション処理と呼ばれる処理を行うことで、キーに対する最新の情報だけを残していきます。

Hashインデックスの内部構造(Hashインデックスより)

SSTableとLSMツリー

SSTable(Sorted String Table)は その名の通り、キーでソートされていることを条件に加えたストレージセグメントになります。

このメリットとしては、セグメントのマージを効率的に行えるようになったり、すべてのキーをメモリに保存しておく必要がなくなったりします。

書き込みに関しては、データベースがクラッシュしてしまうと、直近の書き込みが失われてしまうのですが、ディスク上にログを持つことで復旧できるようになります。(所謂、Write Ahead Logです。)
また、データベースを可変のセグメントに分割してセグメントにはシーケンシャルに書き込みます。

上記のようなSSTable(と同じような原理)を採用しているデータ構造をLSMツリー(Log-Structured Merged-Tree)と呼びます。全文検索エンジン(ElasticSearch, Solrなど)のApache Luceneも同様の手法です。

ログ構造のマージツリー Log Structured Merge Treeより

Bツリー

最も広く使われているインデックス構造はこのBツリーになります。非リレーショナルデータベースにおいて多く使われています。

Bツリーはキーと値のペアをキーでソートされた状態で保持します。
ここまでは上記のSSTableと似たようなものになりますが、Bツリーはデータベースを固定サイズのブロックやページに分割します。

B木(wikipediaより)

OLAP(オンライン分析処理)

データウェアハウスの台頭

OLTPのシステムを分析目的で使うのをやめ、その代わりに別個のデータベースで分析を実行するという流れが企業に発生しました。このデータベースをデータウェアハウスと呼ぶようになりました。

なぜこの流れが発生したのかというと、アドホックな分析クエリをOLTPデータベースで実行しなくなったからになります。
これはクエリの負荷が高く、データセットの大部分をスキャンしてしまうことで、並行して実行されるトランザクションのパフォーマンスを損なう可能性があるからです。

OLAPにおけるインデックスの非効率性

インデックスのアルゴリズムは、OLTPではうまく機能するものの、分析的なクエリに対して答えを返す上ではそれほどうまく働かないことがわかっています。
これはすべての行列をフィルタリングする必要が少ないという理由からです。

スタースキーマとスノーフレークスキーマ

スタースキーマはスター型構造でディメンジョン・テーブルに接続されたファクト・テーブルで構成される。
中心にある頻繁に参照されるテーブルをファクトテーブルと呼び、他のテーブルをディメンションテーブルと呼びます。ファクトテーブルの他の列をディメンションテーブルに格納します。

それに対して、スノーフレークスキーマは階層的に複数のディメンジョン・テーブルに接続されたファクト・テーブルで構成されます。(雪の結晶の形をしているため名付けられた)

スタースキーマは部分的に非正規化された設計になっており、シンプルになっているので分析者などから好まれやすいです。

スノーフレークとスタースキーマの違いと比較より

以下の本では、更に詳細な説明があるので手に取ってみてください。スタースキーマの提唱者であるラルフ・キンボールが解説しています。

列指向ストレージ

OLTPで使われるような行指向ストレージではなく、クエリに必要な列だけをディスクからロードするような列指向がデータウェアハウスではよく採用されています。これは分析に必要なデータは全ての列を扱うことが少ないからです。そうすることで多くの処理を省くことができます。

また、列データを圧縮すれば、さらにディスクに対する負担を下げることができます。この圧縮とはユニークになるように対応させることをいいます。例えば、ビットマップエンコーディングのようなものがあり、エンコードされた列は極めてコンパクトになります。

列志向のストレージは、読み取りのクエリを高速化してくれます。しかし、デメリットとして書き込みが遅くなってしまうという点もあります。(この解決法としてLSMツリーが挙げられています。)

日経クロステックより

マテリアライズドビュー

マテリアライズドビューは、実際にクエリの結果をコピーしたものでディスクに書き込まれた物体を持つビューになります。仮想的なビューは、単にクエリを書きやすくするためのショートカットに過ぎません。(データ量が少なくなるので、クエリに対してコストを抑えることもできます。)

データウェアハウスでは、同じ集計処理や同じ生データを処理することがしばしばあります。その場合にクエリから特に頻繁に利用されるカウントや合計値をキャッシュするために実体化させておきます。

上記のような点からマテリアライズドビューはOLTPでは利用されず、データウェアハウスで頻繁に使われることが多いです。

まとめ

以上、ストレージと抽出について解説しました。

OLTPとOLAPの特徴を解説し、OLTPではインデックスが有効であることが分かりました。また、OLAPでは膨大なデータ量の読み込みが多いので列志向で作成されるこことが多くなっています。

様々なデータウェアハウス製品が登場していますが、基本を抑えることでどんな製品にも対応することができるのではないかと思います。

ストレージと抽出について特に重要な点を解説しました。ただし、非常に量が多いため解説していない部分が多々あります。詳細は本書を手にとってみて下さい。


この記事が気に入ったらサポートをしてみませんか?