0

わかりました、私はしばらくこの問題に取り組んできました。いくつかの回避策を見つけましたが、私が考えた方法でそれを行うことが可能かどうか知りたいです.

私は 2 つのデータベースを持っています。1 つはデータを収集する Web サーバー上のリモート (私はそれと呼びますDB_A)、もう 1 つはこのデータを分析するローカル マシン上 (私はそれと呼びますDB_B) です。テーブルは基本的に同じ構造ですが、処理側 ( DB_B) を追加しましたいくつかの列。

したがって、サーバー側 ( DB_A) は次のようになります。

|UserID|LastActive|InfoA|InfoB|

ローカル側 ( DB_B) では次のようになります。

|UserID|LastActive|InfoA|InfoB|InfoC|

したがって、最初にデータをローカル側にインポートすると、データをInfoC処理NULLしてInfoC. その間、DB_Aは新しいデータで満たされ、更新されます。私が望むのは、データをエクスポートして、上書きせずにフィールドを更新してDB_Aインポートすることです。これにより、まだ設定されていないすべての行を後で処理できますDB_BLastActiveInfoBInfoCInfoC

私がこれまでに見つけたもの:

  • テーブルの構造が異なるため、単純な mysqldump とインポートは機能しません。したがって、mysql を --execute および -X パラメータとともに使用して、XML データファイルを取得します。
  • で XML ファイルをインポートしDB_Bてもエラーは発生しません LOAD XML INFILE 'path/to/file.xml' REPLACE INTO TABLE users;InfoC
  • 代わりにステートメントを使用するINSERT IGNOREと、すでにインポートされているユーザーは明らかに更新されません。

だから私の質問は: 中間テーブルのような回避策を使用せずに MySQL でこれを行う方法はありますか?

追加:これはPHPまたは他の言語を使用して簡単に実行できることを知っていますが、できれば単純なMySQLソリューションに固執したいと思います

編集: Simon のおかげで、tmp データベースを使用するかなり単純なソリューションが得られました。これにより、mysqldump を使用することもでき、遅い XML 方式を使用する必要がなくなります。

# create temporary db (for tweaking performance create it in memory)
DROP TABLE IF EXISTS tmp_users;
CREATE TABLE tmp_users LIKE users; 

# import data (just as an example, this is not mysql syntax)
mysql<users.sql

# this is even simpler than in the answer
# since you don't have to specify values for the select and insert
INSERT INTO users
SELECT * FROM tmp_users
ON DUPLICATE KEY UPDATE 
  LastActive = VALUES(LastActive),
  InfoA = VALUES(InfoA),
  InfoB = VALUES(InfoB);

DROP TABLE IF EXISTS tmp_users;
4

1 に答える 1

1

INSERT を使用することがおそらくこれを行う方法であり、次の行に沿って、「ON DUPLICATE KEY UPDATE」を利用します (ドキュメントへのリンク: http://dev.mysql.com/doc/refman/5.0/en /insert-on-duplicate.html )

-- Set up the insert into DB_B
INSERT INTO DB_B (
  UserID, -- Assuming this is the PK
  LastActive,
  InfoA,
  InfoB,
  InfoC
) 
-- Do whatever you did in your INSERT IGNORE statement, a temp. table is probably most efficient though
SELECT
  UserID,
  LastActive,
  InfoA,
  InfoB,
  NULL -- Assumes that the default for InfoC is NULL
FROM tempTable
-- Now tell MySQL to update any where the PK matches
ON DUPLICATE KEY UPDATE
  LastActive = VALUES(LastActive),
  InfoA = VALUES(InfoA),
  InfoB = VALUES(InfoB)

LOAD DATA だけでこれをまっすぐに行う方法は実際にはわかりませんが、それは実際にはサポートIGNOREしているように見えREPLACE、オプションとしてのみであり、どちらも実際には目的に合わないためです。

于 2012-10-22T13:25:38.990 に答える