目次
- はじめに
- 行指向フォーマットとは
- 列指向フォーマットとは
- まとめ
- 参考
はじめに
データベースは、データ保存形式によって「行指向フォーマット」と「列指向フォーマット」の2種類に分類できます。
ビッグデータ基盤では、「列指向フォーマット」でデータを保存するのが定石となっています。ここでは、なぜ「列指向フォーマット」が使われているのかを説明します。
行指向フォーマットとは
「列指向フォーマット」とは、行単位をひとまとまりとしてデータを保持するような保存形式のことです。一般的なリレーショナルデータベースで使われています。
![image.png (134.4 kB)](https://img.esa.io/uploads/production/attachments/16757/2023/10/25/93654/4d3dc575-6c9e-4607-8e17-c4c7e30c7dcb.png)
行指向フォーマットの特徴
一度のアクセスで特定のIDの全データが取れるため「1レコードを取り出す速度」が早いというメリットがあります。そのため、応答速度が重要なシステム向きです。
一方で、列単位での集計をしようとする場合、非常に時間がかかるというデメリットがあります。特定の列のみ取得したい場合でも、全データを参照する必要があるためです。
そのため、「行指向フォーマット」は分析向きではないデータ保存形式です。
列指向フォーマットとは
「列指向フォーマット」とは、列単位をひとまとまりとしてデータを保持するようなデータの保存形式のことです。
![image.png (149.1 kB)](https://img.esa.io/uploads/production/attachments/16757/2023/10/25/93654/55396de1-5eba-4372-8f45-673bc9e2d8fd.png)
列指向フォーマットの特徴
「行指向フォーマット」とは対象的に、「列指向フォーマット」は一行単位のレコードにアクセスするのには時間がかかるというデメリットがあります。一行のデータを全て集めるために、各列の個々のデータにアクセスが必要なためです。
一方で、列単位でのデータの抽出、集計が高速であるというメリットがあります。特定の列を取得したい場合は、それ以外の列を無視することができるためです。
加えて、列単位では同一型のデータがまとまっており、データを集計・変換して保存することが可能です。そのため、計算・データ容量を節約する工夫ができます。
上記のメリットから、分析に向いているデータ保存形式といえます。
なぜ列指向フォーマットは集計が速いのか?
「列指向フォーマット」は、「行指向フォーマット」に比べて集計速度が高速であると述べました。この仕組みを詳しく見ていきます。「列指向フォーマット」のポイントは、データのまとまり(列ごと)の集計・変換ができることです。
![image.png (149.1 kB)](https://img.esa.io/uploads/production/attachments/16757/2023/10/25/93654/d5213fdc-1f5f-4834-bf7d-195105612df8.png)
列単位では同じ型のデータがまとまっているため、データの統計値の計算や、値の変換ができます。データの集計・変換ができると、データの読み飛ばしや、データの圧縮ができます。
データの読み飛ばし
統計値を使ったデータの読み飛ばしとは、事前に計算した統計情報を使って、データを読み込む前に、集計が必要かどうかを判定することです。
![image.png (149.1 kB)](https://img.esa.io/uploads/production/attachments/16757/2023/10/25/93654/ae85f3bf-c6d4-424a-98ec-0dd019fc2119.png)
例えば、上記の例で「給与¥10,000,000」の従業員を抽出する場合を考えます。この例では、データ自体を見なくても、給与カラムの最大値のみを見て計算不要と判断できます。このように統計値を使うことで、計算リソースを削減することができます。
データの圧縮
データの圧縮とは、もともとの情報を残したまま、容量を減らした別のデータ形式に変換することを指します。データの変換には様々な手法があります。ここで、代表的なデータ圧縮方法を説明します。
- Bit-Vector Encoding
- Delta Encoding
- Dictionary Encoding
- NULL Suppression
- Run-Length Encoding
Bit-Vector Encoding
Bit-Vector Encodingは、各異なる値に対してビットベクトル(ビットマップ)を割り当て、その値がデータセットの特定の位置に存在する場合にはその位置のビットを1に、存在しない場合には0に設定するという方法です。
例えば、「色」のデータを考えます。
赤, 赤, 緑, 青, 緑
このデータに対してBit-Vector Encodingを適用すると、以下のようなビットマップが生成されます。
赤 -> 11000 緑 -> 00101 青 -> 00010
この例では、”赤” は1番目と2番目の位置に存在するので、そのビットマップは “11000” となります。他の色も同様にエンコードされます。
Delta Encoding
Delta Encodingは、データを一つ前の項目との差分として記録する方法です。日付列(Unixtime)などで特に有効です。
例えば、「UNIXTIME」形式のデータを考えます。
1661301970, 1661301975, 1661302000, 1661302500, 1661302555
このデータに対してDelta Encodingを適用すると、以下のようなデータ形式に変更されます。
1661301970, +5, +25, +500, +5
上記の例では、差分を記録することで、桁を減らしてデータを圧縮することができています。
Dictionary Encoding
Dictionary Encodingは、繰り返し現れる値(例えば、文字列や数値)を一意の短いコード(通常は整数)に置き換えて格納する方法です。文字列データを、コード値とマスタで保存するようなイメージです。文字列形式で、データの種類が少ない列に特に有効です。
例えば、以下のような「果物」のデータを考えます。
"apple", "banana", "apple", "cherry", "banana"
上記のデータをコード地に変換するため、以下のような辞書を用意します。
{ "apple": 0, "banana": 1, "cherry": 2 }
この辞書によって、以下のようなデータ形式に変更されます。
0, 1, 0, 2, 1
NULL Suppression
NULL Suppressionは、列の値がNULLである場合に、そのNULL値を物理的に保存しないようにする方法です。NULLの値自体を保持する代わりに、どこにいくつNULLがあるかをメタ情報として保持します。NULLの多い列の圧縮に有効です。
例えば、以下のようなデータを考えます。
5, NULL, NULL, 9, 10, NULL, 12
このデータに対してNULL Suppressionを適用すると、このデータは物理的には以下のような形式で保存されます。
5, 9, 10, 12
NULLの位置やその他のメタデータ情報も併せて保存されることで、必要なときに元のデータを復元できます。
Run-Length Encoding
Run-Length Encodingは、データの繰り返し項目と、回数をペアにして保存する方法です。繰り返しが続くデータほど有効です。
例えば、以下のようなデータを考えます。
AAAABBBCCDAA
このデータに対してRun-Length Encodingを適用すると、以下のような形式で保存されます。
4A3B2C1D2A
この変換によって、繰り返しのあるデータを減らすことができます。
まとめ
この記事では、ビッグデータ基盤で定石として利用されている「列指向フォーマット」の仕組みについて説明しました。
「列指向フォーマット」は、特定の列のデータに高速にアクセスしやすいデータ保存形式です。加えて、値の集計・変換ができるため、リソースを削減する工夫がしやすいことから、
大規模な分析用データの保存・利用に適しているため、ビッグデータ基盤で使用されています。