リアルタイム データ ウェアハウスの構築 質問 4: あなたは唖然としていますが、Jdbc の SQL コネクタが削除ステートメントを実行できることを知らず、あえてデータを Mysql にドロップするのですか?

実際、JDBC コネクタは削除ステートメントも実行します。update_before および delete タイプのメッセージを受信した後、DDL で構成された主キーに従って削除ステートメントが生成および実行され、where 条件のフィールドが主キーになります。

まずは公式 Web サイトの内容を見てみましょう。
主キーが DDL で定義されている場合、JDBC レシーバーは通常の INSERT ステートメントの代わりに upsert セマンティクスを使用します。Upsert セマンティクスとは、基になるデータベースに一意制約違反がある場合に、新しい行を自動的に追加するか、既存の行を更新することを指し、冪等性が提供されます。

upsert には標準の構文がないため、次の表に、使用されるデータベース固有の DML を示します。
ここに画像の説明を挿入

これはデータの挿入のみを目的としており、実際には、JDBC コネクタは削除ステートメントも実行します。update_before および delete タイプのメッセージを受信した後、DDL で構成された主キーに従って削除ステートメントが生成および実行され、where 条件のフィールドが主キーになります。

以下は、TableBufferReducedStatementExecutor クラスのコア ロジックです。

    @Override
    public void addToBatch(RowData record) throws SQLException {
        RowData key = keyExtractor.apply(record);
        boolean flag = changeFlag(record.getRowKind());
        RowData value = valueTransform.apply(record); // copy or not
        reduceBuffer.put(key, Tuple2.of(flag, value));
    }

    /**
     * Returns true if the row kind is INSERT or UPDATE_AFTER, returns false if the row kind is
     * DELETE or UPDATE_BEFORE.
     */
    private boolean changeFlag(RowKind rowKind) {
        switch (rowKind) {
            case INSERT:
            case UPDATE_AFTER:
                return true;
            case DELETE:
            case UPDATE_BEFORE:
                return false;
            default:
                throw new UnsupportedOperationException(
                        String.format(
                                "Unknown row kind, the supported row kinds is: INSERT, UPDATE_BEFORE, UPDATE_AFTER,"
                                        + " DELETE, but get: %s.",
                                rowKind));
        }
    }

    @Override
    public void executeBatch() throws SQLException {
        for (Map.Entry<RowData, Tuple2<Boolean, RowData>> entry : reduceBuffer.entrySet()) {
            if (entry.getValue().f0) {
                upsertExecutor.addToBatch(entry.getValue().f1);
            } else {
                // delete by key
                deleteExecutor.addToBatch(entry.getKey());
            }
        }
        upsertExecutor.executeBatch();
        deleteExecutor.executeBatch();
        reduceBuffer.clear();
    }

おすすめ

転載: blog.csdn.net/hbly979222969/article/details/131205488
おすすめ