ユニークキーモデルでのデータ更新
この文書では、様々なロード方法を使用してDoris unique keyモデルでデータを更新する方法を紹介します。
行全体の更新
Stream Load、Broker Load、Routine Load、Insert Intoなど、Dorisがサポートする方法を使用してunique keyモデルにデータをロードする際、既存のプライマリキーデータ行が存在しない場合は新しいデータが挿入されます。既存のプライマリキーデータ行が存在する場合は更新されます。これは、Doris unique keyモデルでのロード操作が「upsert」モードで動作することを意味します。既存レコードを更新するプロセスはデフォルトで新しいレコードをロードするプロセスと同じであるため、詳細についてはデータロードのドキュメントを参照してください。
部分列更新
部分列更新では、すべてのフィールドを変更せずにTable内の特定のフィールドを更新できます。この操作を実行するためにUpdate文を使用できますが、これは通常、行全体を読み取り、目的のフィールドを更新し、それを書き戻すことを含みます。この読み書きトランザクションは時間がかかり、大規模なデータ書き込みには適していません。Dorisは、unique keyモデルのロード更新で部分列データを直接挿入または更新する機能を提供しており、最初に行全体を読み取る必要性を回避することで、更新効率を大幅に向上させます。
- バージョン2.0では、Unique KeyのMerge-on-Write実装でのみ部分列更新をサポートしています。
- バージョン2.0.2以降、INSERT INTOを使用した部分列更新がサポートされています。
- 同期マテリアライズドビューを持つTableでは部分列更新はサポートされていません。
- スキーマ変更を実行中のTableでは部分列更新は許可されていません。
適用シナリオ
- リアルタイム動的列更新:Table内の特定のフィールドの頻繁な更新が必要。例えば、広告/推薦システムでのリアルタイム分析と意思決定のために、ユーザータグTableで最新のユーザー行動に関連するフィールドを更新する場合。
- 複数のソースTableを1つの大きなワイドTableにマージする。
- データ修正。
使用例
Dorisに注文Tableorder_tblがあると仮定します。ここで、注文idがKey列、注文ステータスと注文金額がValue列です。データの状態は以下のとおりです:
| Order id | Order Amount | Order Status |
|---|---|---|
| 1 | 100 | Pending Payment |
+----------+--------------+--------------+
| order_id | order_amount | order_status |
+----------+--------------+--------------+
| 1 | 100 | Pending Payment |
+----------+--------------+--------------+
1 row in set (0.01 sec)
ユーザーが支払いをクリックした後、DorisシステムはorderID '1'の注文のorder statusを'Pending Shipment'に変更する必要があります。
Loadメソッドを使用した部分列更新
StreamLoad/BrokerLoad/RoutineLoad
以下のCSVファイルを準備してください:
1,Pending Shipment
読み込み時に以下のヘッダーを追加してください:
partial_columns:true
columnsに読み込む列を指定します(すべてのキー列を含める必要があります)。以下はStream Loadの例です:
curl --location-trusted -u root: -H "partial_columns:true" -H "column_separator:," -H "columns:order_id,order_status" -T /tmp/update.csv http://127.0.0.1:8030/api/db1/order_tbl/_stream_load
INSERT INTO
全てのデータモデルにおいて、部分的なカラムが指定された場合のINSERT INTOのデフォルトの動作は、行全体を書き込むことです。誤用を防ぐため、Merge-on-Write実装では、INSERT INTOはデフォルトで行全体のUPSERTのセマンティクスを維持します。部分的なカラム更新を有効にするには、以下のセッション変数を設定してください:
SET enable_unique_key_partial_update=true;
INSERT INTO order_tbl (order_id, order_status) VALUES (1, 'Pending Shipment');
セッション変数enable_insert_strictはデフォルトでtrueになっており、デフォルトでstrict modeが有効になることに注意してください。strict modeでは、部分列更新において存在しないキーの更新は許可されません。部分列更新のinsert文を使用して存在しないキーを挿入するには、enable_unique_key_partial_updateをtrueに、enable_insert_strictをfalseに設定してください。
Flink Connector
Flink Connectorを使用する場合は、以下の設定を追加してください:
'sink.properties.partial_columns' = 'true',
sink.properties.columnで読み込む列を指定してください(すべてのキー列を含める必要があります)。
更新結果
更新後の結果は以下の通りです:
+----------+--------------+--------------+
| order_id | order_amount | order_status |
+----------+--------------+--------------+
| 1 | 100 | Pending Shipment |
+----------+--------------+--------------+
1 row in set (0.01 sec)
使用上の注意
Merge-on-Write実装は、最適なクエリパフォーマンスを確保するために書き込み時にデータの完全な行を完成させる必要があるため、部分的な列更新に使用すると部分ロードのパフォーマンスが低下する可能性があります。
パフォーマンス最適化の提案:
- NVMeを搭載したSSDまたは高速SSDクラウドディスクを使用してください。データの完成時に大量の履歴データを読み取るため、高い読み取りIOPSとスループットが発生します。
- 行ストレージを有効にすると、データ完成時に発生するIOPSを削減でき、ロードパフォーマンスを大幅に向上させることができます。Table作成時に以下のプロパティを設定して行ストレージを有効にしてください:
"store_row_column" = "true"
現在、同一バッチデータ書き込みタスク(ロードタスクまたはINSERT INTOのいずれか)内のすべての行は、同じ列のみを更新できます。異なる列でデータを更新するには、異なるバッチで書き込む必要があります。
将来のバージョンでは、柔軟な列更新をサポートし、ユーザーが同一バッチロード内の各行で異なる列を更新できるようになります。