2

データベース レコードがデータの入力ストリームに基づいて定期的に作成されるシステムに取り組んでいます。ときどき、別々に作成された 2 つのレコードを 1 つにマージする必要があるという証拠を提供する何らかの入力が行われます。データベースでマージを実行する方法に関する推奨事項を探しています。

メイン テーブル (この時点では単なる設計です) には、一意の ID (私のシステムではデータベース、MySQL によって割り当てられるメイン ID と呼びます) といくつかのデータ フィールドで構成されるレコードが含まれます。メイン ID を使用してレコードをメイン テーブルのレコードにリンクする他のテーブルもあります。

MainTable:
int   mainID
blob  data
...

OtherTable:
int   otherID
int   mainID
blob  otherData
...

各レコードが外部プロセスまたはシステムと共有されたことがない場合は、データ フィールドをあるレコードから別のレコードに何らかの形でブレンドし、そのレコードを削除するのは簡単です。他のテーブルのメイン ID フィールドを、保持しているメイン ID 値に更新するのも簡単です (退屈で非効率的である場合)。

各レコードの ID がシステム外で共有されている場合、事態は複雑になります。この場合、削除された ID を使用したクエリが単純に失敗するのは不合理だと思いますが、そうでないと確信することもできます。

私が考えているアイデアは、元のメイン ID と現在のメイン ID という 2 つのキー フィールドを持つマージ テーブルを導入することです。その目的は、1 つのメイン ID を別の ID にエイリアスすることです。各メイン テーブル レコードが作成されると、新しく作成されたメイン テーブル レコードのメイン ID をそれ自体にマッピングするレコードをマージ テーブルに追加します。マージが発生した場合、レコードのマージ テーブル内の現在のメイン ID フィールドを、マージされるメイン レコードの元のメイン ID で更新するだけです。次に、メイン ID に基づくすべてのクエリについて、マージ テーブルを介してその ID をマップし、実際に使用する有効なメイン ID を見つけます。

MergeTable:
int   mergeID
int   originalMainID
int   currentMainID

これは良いテクニックですか?マッピングは SQL クエリでシームレスに実行できますか? 代わりに検討すべき標準的またはより優れた手法はありますか?

このトピックについて調査を行ったところ、驚くほど少数の例が見つかりました。この質問は近いですが、マージのシナリオは私のものとは異なります。私はデータベースについて少し知っていますが、決して専門家ではないので、検索するのに適切な用語を知らないと思います。

4

1 に答える 1

3

私はあなたのデザインのアイデアが好きですが、すべてのレコードではなく、置換されたレコードのみをマージ テーブルに保存するものを検討してください。次のクエリの場合、これによりストレージが削減され、速度が向上します。

SELECT *
  FROM MainTable
  WHERE mainID = 1
UNION ALL
SELECT MainTable.*
  FROM MergeTable
  INNER JOIN MainTable
    ON MainTable.mainID = MergeTable.currentMainID
  WHERE MergeTable.originalMainID = 1
LIMIT 1

ほとんどの場合、最初のクエリは成功して結果を返し、LIMIT が満たされているため、MySQL は 2 番目のクエリを中止するという考え方です。最初のクエリが結果を返さない場合は、2 番目のクエリに進み、マージ テーブルで結合を実行して、マージされているかどうかを確認します。

MySQLによると、LIMITに関して:

MySQL が必要な数の行をクライアントに送信するとすぐに、SQL_CALC_FOUND_ROWS を使用していない限り、クエリは中止されます。

マージされたレコードがルールではなく例外である場合、これにより非常に多くの結合が節約されます。

UNION クエリが難しすぎる場合は、2 つのクエリでこれを行うこともできます。レコードが存在するかどうかを確認するだけで、存在しない場合はマージ テーブルを確認できます。

于 2012-05-23T22:00:45.690 に答える