使用上の注意
カラム型の提案
Table作成時のカラム型の提案:
- Keyカラムはすべての Value カラムの前に配置する必要があります。
- 可能な限り、整数型を選択してください。これは、整数型の計算と検索効率が文字列よりもはるかに高いためです。
- 異なる長さの整数型を選択する場合は、十分性の原則に従ってください。
- VARCHARおよびSTRING型の長さについても、十分性の原則に従ってください。
Aggregate モデルの制限事項
このセクションでは、Aggregate モデルの制限事項について説明します。
Aggregate モデルは集約されたデータのみを表示します。これは、まだ集約されていないデータ(たとえば、2つの異なるインポートバッチ)の表示一貫性を確保する必要があることを意味します。以下では、例を用いてさらに詳しく説明します。
以下のTableスキーマがあるとします:
| ColumnName | タイプ | AggregationType | Comment |
|---|---|---|---|
| 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;
結果は5になり、1ではありません。
一方で、この一貫性の保証により、一部のクエリの効率が大幅に低下する可能性があります。
基本的な count (*) クエリを例に取ります:
SELECT COUNT(*) FROM table;
他のデータベースでは、このようなクエリは迅速に結果を返します。実際の実装では、モデルはインポート時に行をカウントして統計を保存するか、クエリ時に特定のカラムのデータのみをスキャンしてカウント値を取得することで、非常に少ないオーバーヘッドでクエリ結果を得ることができるためです。しかし、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 (*) をシミュレートすることをお勧めします。この方法では、前の例のTableスキーマは以下のように変更されます:
| ColumnName | タイプ | AggregationType | Comment |
|---|---|---|---|
| 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 |
上記では count カラムを追加し、その値は常に1になります。そのため select count (*) from table; の結果は select sum (count) from table; の結果と同等になります。後者は前者よりもはるかに効率的です。しかし、この方法にも欠点があります。それは、ユーザーが AGGREGATE KEY カラムで同じ値を持つ行をインポートしないことが必要なことです。そうでなければ、select sum (count) from table; は select count (*) from table; のセマンティクスではなく、元々インポートされたデータの行数のみを表現できます。
別の方法は、値1で集約型がREPLACEの cound カラムを追加することです。そうすれば 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 モデルでは、Table作成時にKeyカラムが指定されますが、いくつかの違いがあります:Duplicate モデルでは、TableのKeyカラムは単なる「ソートカラム」と見なすことができ、一意識別子ではありません。AggregateおよびUnique モデルでは、Keyカラムは「ソートカラム」と「一意識別子カラム」の両方です。
データモデル選択の提案
データモデルはTable構築時に確立され、その後は取り消し不可能であるため、適切なデータモデルを選択することは非常に重要です。
- Aggregate モデルは、事前集約により、データスキャン量とクエリ計算を大幅に削減できます。したがって、固定パターンのレポートクエリシナリオに非常に適しています。しかし、このモデルは
count (*)クエリには不親切です。また、Valueカラムの集約方法が固定されているため、他のタイプの集約クエリではセマンティクスの正確性を考慮する必要があります。 - Unique モデルは、一意のプライマリキーを必要とするシナリオでプライマリキーの一意性を保証します。欠点は、クエリでROLLUPなどの事前集約によってもたらされる利点を活用できないことです。集約クエリに対して高パフォーマンス要件があるユーザーには、バージョン1.2以降に新しく追加されたMerge on Write実装の使用をお勧めします。
- Duplicate モデルは、任意の次元のアドホッククエリに適しています。事前集約機能の利点を活用できない場合もありますが、Aggregate モデルを制約する要因に制限されず、カラム型ストレージの利点(すべてのKeyカラムではなく、関連するカラムのみを読み取る)を十分に発揮できます。
- ユーザーが部分更新を使用する必要がある場合は、ドキュメントpartial-updateを参照してください。