使用上の注意
カラム型の推奨事項
テーブル作成時のカラム型の推奨事項:
- KeyカラムはすべてのValueカラムより前に配置する必要があります。
- 可能な限り、整数型を選択してください。整数型の計算および検索効率は文字列よりもはるかに高いからです。
- 異なる長さの整数型を選択する場合は、十分性の原則に従ってください。
- VARCHARおよびSTRING型の長さについても、十分性の原則に従ってください。
Aggregateモデルの制限事項
このセクションでは、Aggregateモデルの制限事項について説明します。
Aggregateモデルは集約されたデータのみを提示します。つまり、まだ集約されていないデータ(例えば、2つの異なるインポートバッチ)の表示一貫性を確保する必要があります。以下では例を用いてさらに詳しく説明します。
以下のテーブルスキーマがあるとします:
| ColumnName | タイプ | AggregationType | コメント |
|---|---|---|---|
| user_id | LARGEINT | User ID | |
| date | DATE | Date when the data are imported | |
| cost | BIGINT | SUM | Total user consumption |
以下のように2つのデータバッチがストレージエンジンにインポートされたと仮定します:
batch 1
| user_id | date | cost |
|---|---|---|
| 10001 | 2017-11-20 | 50 |
| 10002 | 2017-11-21 | 39 |
batch 2
| user_id | date | cost |
|---|---|---|
| 10001 | 2017-11-20 | 1 |
| 10001 | 2017-11-21 | 5 |
| 10003 | 2017-11-22 | 22 |
ご覧のように、これら2つのインポートバッチでのUser 10001に関するデータはまだ集約されていません。しかし、ユーザーが以下のように集約されたデータのみをクエリできるようにするため:
| user_id | date | cost |
|---|---|---|
| 10001 | 2017-11-20 | 51 |
| 10001 | 2017-11-21 | 5 |
| 10002 | 2017-11-21 | 39 |
| 10003 | 2017-11-22 | 22 |
データの表示一貫性を確保するため、クエリエンジンに集約オペレーターを追加しました。
さらに、集約カラム(Value)において、集約型と一致しない集約クラスのクエリを実行する場合は、セマンティクスに注意してください。例えば、上記の例で以下のクエリを実行した場合:
SELECT MIN(cost) FROM table;
結果は1ではなく5になります。
一方、この一貫性保証は一部のクエリで効率を大幅に低下させる可能性があります。
基本的な count (*) クエリを例に取ると:
SELECT COUNT(*) FROM table;
他のデータベースでは、このようなクエリは迅速に結果を返します。実際の実装では、モデルはインポート時に行をカウントして統計を保存するか、クエリ時に特定の1つのカラムのデータのみをスキャンして非常に少ないオーバーヘッドでカウント値を取得することで、クエリ結果を得ることができるからです。しかし、DorisのAggregationモデルでは、このようなクエリのオーバーヘッドは大きくなります。
前の例について:
batch 1
| user_id | date | cost |
|---|---|---|
| 10001 | 2017-11-20 | 50 |
| 10002 | 2017-11-21 | 39 |
batch 2
| user_id | date | cost |
|---|---|---|
| 10001 | 2017-11-20 | 1 |
| 10001 | 2017-11-21 | 5 |
| 10003 | 2017-11-22 | 22 |
最終的な集約結果は以下のようになるため:
| user_id | date | cost |
|---|---|---|
| 10001 | 2017-11-20 | 51 |
| 10001 | 2017-11-21 | 5 |
| 10002 | 2017-11-21 | 39 |
| 10003 | 2017-11-22 | 22 |
select count (*) from table;の正しい結果は4になるはずです。しかし、モデルがuser_idカラムのみをスキャンしてクエリ時に集約操作を行った場合、最終結果は3(10001、10002、10003)になります。集約操作を行わない場合、最終結果は5(2つのバッチで合計5行)になります。明らかに、両方の結果は間違っています。
正しい結果を得るために、user_idとdateの両方のカラムを読み取り、クエリ時に集約を実行する必要があります。つまり、count (*)クエリでは、Dorisはセマンティクス的に正しい結果を得るために、すべてのAGGREGATE KEYカラム(この場合、user_idとdate)をスキャンして集約する必要があります。これは、集約されたカラムが多い場合、count (*)クエリが大量のデータのスキャンを伴う可能性があることを意味します。
そのため、頻繁にcount (*)クエリを実行する必要がある場合は、値1と集約型SUMのカラムを追加してcount (*)をシミュレートすることをお勧めします。この方法では、前の例のテーブルスキーマは以下のように変更されます:
| ColumnName | タイプ | AggregationType | コメント |
|---|---|---|---|
| user ID | BIGINT | User ID | |
| date | DATE | Date when the data are imported | |
| Cost | BIGINT | SUM | Total user consumption |
| count | BIGINT | SUM | For count queries |
上記では、常に1の値を持つcountカラムを追加しているため、select count (*) from table;の結果はselect sum (count) from table;の結果と等価になります。後者の方が前者よりもはるかに効率的です。ただし、この方法にも欠点があります。それは、ユーザーがAGGREGATE KEYカラムで同じ値を持つ行をインポートしないことが求められることです。そうでなければ、select sum (count) from table;はselect count (*) from table;のセマンティクスではなく、元のインポートデータの行数のみを表現することになります。
別の方法は、値1で集約型がREPLACEのcountカラムを追加することです。そうすれば、select sum (count) from table;とselect count (*) from table;は同じ結果を生成できます。さらに、この方法はインポートデータで同じAGGREGATE KEYカラムがないことを要求しません。
MoW Unique Keyモデル
UniqueモデルのMerge on Write実装は、Aggregateモデルと同じ制限を課しません。Merge on Writeでは、モデルは各インポートされたrowsetにdelete bitmapを追加して、上書きまたは削除されるデータをマークします。前の例を使用して、Batch 1がインポートされた後、データの状態は以下のようになります:
batch 1
| user_id | date | cost | delete bit |
|---|---|---|---|
| 10001 | 2017-11-20 | 50 | false |
| 10002 | 2017-11-21 | 39 | false |
Batch 2がインポートされた後、最初のバッチの重複行は削除済みとしてマークされ、2つのバッチのデータの状態は以下のようになります:
batch 1
| user_id | date | cost | delete bit |
|---|---|---|---|
| 10001 | 2017-11-20 | 50 | true |
| 10002 | 2017-11-21 | 39 | false |
batch 2
| user_id | date | cost | delete bit |
|---|---|---|---|
| 10001 | 2017-11-20 | 1 | false |
| 10001 | 2017-11-21 | 5 | false |
| 10003 | 2017-11-22 | 22 | false |
クエリでは、delete bitmapでtrueとしてマークされたすべてのデータは読み取られないため、データ集約は不要です。上記のデータには4つの有効な行があるため、クエリ結果も4になるはずです。これは、1つのカラムのデータのみをスキャンするため、最小限のオーバーヘッドも可能にします。
テスト環境では、Uniqueモデルの Merge on Write におけるcount(*)クエリは、Aggregateモデルよりも10倍高いパフォーマンスを提供します。
Duplicateモデル
Duplicateモデルは、集約セマンティクスが含まれないため、Aggregateモデルと同じ制限を課しません。任意のカラムに対して、count (*)クエリでセマンティクス的に正しい結果を返すことができます。
Keyカラム
Duplicate、Aggregate、およびUniqueモデルについて、Keyカラムはテーブル作成時に指定されますが、いくつかの違いがあります:Duplicateモデルでは、テーブルのKeyカラムは単に「ソートカラム」と見なすことができ、一意の識別子ではありません。AggregateおよびUniqueモデルでは、Keyカラムは「ソートカラム」と「一意識別子カラム」の両方です。
データモデル選択の推奨事項
データモデルはテーブルの構築時に確立され、その後取り消すことができないため、適切なデータモデルを選択することは非常に重要です。
- Aggregateモデルは、事前集約によりスキャンされるデータ量とクエリ計算を大幅に削減できます。したがって、固定パターンのレポートクエリシナリオに非常に適しています。しかし、このモデルは
count (*)クエリには不向きです。また、Valueカラムの集約方法が固定されているため、他の種類の集約クエリではセマンティクスの正確性を考慮する必要があります。 - Uniqueモデルは、一意のプライマリキーが必要なシナリオでプライマリキーの一意性を保証します。欠点は、クエリでROLLUPなどの事前集約によってもたらされる利点を活用できないことです。集約クエリに高パフォーマンス要件があるユーザーには、バージョン1.2以降で新しく追加されたMerge on Write実装の使用をお勧めします。
- Duplicateモデルは、任意の次元のアドホッククエリに適しています。事前集約機能の利点を活用できない場合がありますが、Aggregateモデルを制約する制限を受けず、カラム型ストレージの利点(関連するカラムのみを読み取り、すべてのKeyカラムではない)を十分に発揮できます。
- ユーザーがpartial-updateを使用する必要がある場合は、ドキュメントpartial-updateを参照してください。