目次
前回のおさらい(前提条件)
前回、検証を進めるにあたり、以下のような条件を想定しました。
- 製造業の企業
- 全国に10箇所の生産ライン工場を持つ
- 工場は24時間稼働
- 工場で稼働するセンサのデータを収集し、長期的(10~20年)にデータを蓄積し、効率的な稼動を分析するためにデータを利用したい
- 収集するセンサデータの生成頻度は1分とし、センサの数は3000個/1工場
- データは非構造化データ
- 工場のシステムと接続するため、セキュリティ面からオフライン環境(インターネット接続はしない)とする
検証環境について
本テーマでは検証するにあたって、RDBSをSQLServer2016 Developer Edition(Enterprise Editionと同等)を使用していきたいと思います。
オンプレミスRDBSはOracle、MySQL、PostgreSQL等・・・様々あるが、私自身がSQLServerを使う機会が多かったことがあり、今回はSQLServerを主軸として検証するが、他DBMSでも同等の機能などがあればピックアップして紹介していきます。
OS | Windows Server2016 |
DBMS | SQLServer2016 Developer Edition |
テーブル構成について
CREATE TABLE DataTable ( plant_id as varchar(2) NOT NULL, --工場ID sampling_at as smalldatetime NOT NULL, --取得日時 sensor_name as varchar(15) NOT NULL, --センサ名 valueasdecimal(15,3), --値 CONSTRAINT [DataTablePK] PRIMARYKEY CLUSTERED ( plant_id, sampling_at, sensor_name ) );
plant_id | sampling_at | sensor_name | value |
01 | 2018-12-01 00:00:00 | Sensor_0001 | 12.345 |
01 | 2018-12-01 00:01:00 | Sensor_0001 | 13.456 |
ヒープデータ量の推定
今回は、上記のテーブル構成でデータを蓄積すると考え、データ量がどれほどとなるのかを推定したいと思います。
まずはヒープのデータ量を推定します。
ヒープとは、クラスター化インデックスを使用しないテーブルのことを指します。
上記のテーブル構成であればプライマリキーを使用していない状態になります。
つまりインデックス(索引)を含まない単純なデータ量を見積りたいと思います。
1. 想定レコード数
レコード数は、
- 生成頻度が1分
- 24時間稼働
- 10箇所の工場
- センサの数は3000個/1工場
- 少なくとも10年間のデータを蓄積
Num_Rows(レコード数) = ((24 * 60) × (365 × 10)) × (3000 × 10) = 157,680,000,000レコード (約1500億レコード)
2. NULL分の確保領域
各列のNULL分を確保する領域が予約されるため、以下の容量が必要となります。
NULL_Bitmap(NULL予約領域) = 2 + ((列(固定長および可変長)の総数) + 7) / 8)
= 2 + ((4 + 7) / 8) = 3.375
小数部は無視されるので、NULL_Bitmap = 3となります。
3. 行あたりのデータ量
固定長列の合計バイトサイズは以下となります。
plant_id : varchar(2) = 2 + 2 = 4 byte
sampling_at : smalldatetime = 4 byte
sensor_name : varchar(15) = 15 + 2 = 17 byte
Fixed_Data_Size(固定長列の合計バイトサイズ) = 4 + 4 + 17 = 25 byte
decimal型は可変長型なので、最大サイズを考慮して以下となります。
value : decimal(15,3) = 2 + (1(可変長列数) × 2) + 18 = 22 byte
Variable_Data_Size(可変長列の最大バイトサイズ) = 22 byte
Row_Size(1行あたりのデータ量) = Fixed_Data_Size + Variable_Data_Size + NULL_Bitmap + 行ヘッダオーバヘッド(4 byte)
= 25 + 22 + 3 + 4 = 54 byte
4. 1ページあたりの行数
1ページあたりに格納できるデータ量は8096 byteです。
また、行は複数のページにまたがることはできないので、小数以下は切り捨てます。
Row_Per_Page(1ページあたりの行数) = 8096 / (Row_Size + 2)
= 8096 / (54 + 2) = 144.57 = 144行/ページ
5. すべての行を格納するページ数
全データを格納するためのページ数を計算します。
Num_Pages(全ページ数) = Num_Rows / Row_Per_Page
= 157,680,000,000 / 144 = 1,095,000,000 ページ (約10億ページ)
6. ヒープにデータを格納するために必要な領域
1ページ当たりの総バイト数は8192 byteなので、
ヒープのサイズ (バイト) = 8192 × Num_Pages
= 8192 × 1,095,000,000 = 8,970,240,000,000 byte(約9兆byte)
= 8.97 Tbyte
以上で、ヒープのデータ量だけで9テラバイト程度になることがわかりました。
ヒープサイズの見積もりはこちら
データ量だけで9テラバイト程度と推定されたので、ビッグデータと呼べるくらいには多量なデータですね。
このデータ量は、インデックスを含んでいない純粋なデータ量なので、テーブル全体のデータ量はさらに倍近くに大きくなります。
また、チューニング等で非クラスター化インデックスを追加するなどするとさらに増加することが考えられます。
他RDBSでのデータ量推定
Oracle
内容は変わっていないのでしょうか。
MySQL
InnoDBのページサイズは16kbとSQLServerよりも大きいです。