10

customers次のフィールドとレコードを含むテーブルがあるとします。

id   first_name   last_name   email                  phone
------------------------------------------------------------------------
1    Michael      Turley      mturley@whatever.com   555-123-4567
2    John         Dohe        jdoe@whatever.com      
3    Jack         Smith       jsmith@whatever.com    555-555-5555
4    Johnathan    Doe                                123-456-7890

このテーブルに関連する外部キーを持つ、、ordersなどrewardsの他のいくつかのテーブルがあります。receiptscustomer_idcustomers.id

ご覧のとおり、彼らの無限の知恵の中で、私のユーザーはJohn Doeの重複レコードを作成しました。これには、一貫性のないスペルと欠落したデータが含まれています。管理者はこれに気づき、顧客2と4を選択して、[マージ]をクリックします。次に、各フィールドなどに対して正しい値を選択するように求められ、PHPは、マージされたレコードが次のようになると判断します。

id   first_name   last_name   email                  phone
------------------------------------------------------------------------
?    John         Doe         jdoe@whatever.com      123-456-7890

Doe氏がいくつかの注文を出し、報酬を獲得し、領収書を生成したと仮定します。ただし、これらの一部はID 2に関連付けられており、一部はID4に関連付けられています。マージされた行は他​​のすべての外部キーと一致する必要があります元の行と一致したテーブル。

これが私が何をすべきかわからないところです。私の本能はこれを行うことです:

DELETE FROM customers WHERE id = 4;

UPDATE customers
SET first_name = 'John',
    last_name  = 'Doe',
    email      = 'jdoe@whatever.com',
    phone      = '123-456-7890'
WHERE id = 2;

UPDATE orders, rewards, receipts
SET customer_id = 2
WHERE customer_id = 4;

それはうまくいくと思いますが、後でcustomer_id外部キーを持つ別のテーブルを追加する場合は、戻ってそのテーブルをマージ関数の2番目のUPDATEクエリに追加することを忘れないでください。そうしないと、整合性が失われるリスクがあります。

これを行うには、より良い方法が必要です。

4

4 に答える 4

6

私はグーグルからここに来ましたこれは私の2セントです:

SELECT `TABLE_NAME` 
FROM `information_schema`.`KEY_COLUMN_USAGE` 
WHERE REFERENCED_TABLE_SCHEMA='DATABASE'
  AND REFERENCED_TABLE_NAME='customers'
  AND REFERENCED_COLUMN_NAME='customer_id'

保険用のデータベースを追加します(誰かがいつデータベースをコピーするかはわかりません)。

ここでは、列名を探す代わりに、外部キー自体を調べます。

削除時の制限を変更して制限すると、子が削除/移行される前に何も削除できなくなります

于 2011-06-03T13:05:14.140 に答える
2

簡単に言えば、(私が考えることができる)より良い方法はありません。

それはトレードオフです。これらのインスタンスがたくさんある場合は、新しい顧客を追加する前に、既存の顧客をチェックするためのより堅牢なアルゴリズムを作成するために時間を費やす価値があるかもしれません(つまり、姓名のバリエーションをチェックし、追加する人にそれらを提示します顧客は、この新しい顧客を追加することを本当に確信しているかどうかを2、3回尋ねます。これらのインスタンスが多くない場合は、その時間を投資する価値がない可能性があります。

それを除けば、あなたのアプローチが私が考えることができる唯一の方法です。実際には両方のレコードを削除し、マージされたデータを使用して新しいレコードを作成します。これにより、古いレコードを再利用するのではなく、新しい顧客IDが作成されますが、これは個人的な好みです。機能的には、アプローチと同じです。マージ関数に戻って変更し、customer.idフィールドに新しい関係を反映することを忘れないでください。

于 2011-03-08T19:07:07.747 に答える
2

少なくとも、削除のトリガーがカスケード効果を引き起こすのを防ぐために、私は最初に

SomeTable set CustomerID = CorrectValueを更新します。ここで、CustomerID = WrongValue

(すべてのテーブルでそれを行います)...

次に、CustomerID=WrongValueである顧客から削除します

重複データについては...特定の情報が不足している場合は、どの「ウィル・スミス、ビル・スミス、ウィリアム・スミス」を見つけてください...完全に合法的な別の人である可能性があります。

于 2011-03-08T19:08:19.360 に答える
0

私のコメントの更新として:

use information_schema;
select table_name from columns where column_name = 'customer_id';

次に、結果のテーブルをループし、それに応じて更新します。

個人的には、免除する必要のあるcustomer_id列を含むテーブルがある場合、これは危険である可能性があるため、本能的なソリューションを使用します。

于 2011-03-08T19:15:28.253 に答える