0

好的,我已经在这个问题上坐了一段时间,我找到了一些解决方法,但我想知道是否可以按照我的想法进行操作。

我有 2 个数据库,一个DB_A位于网络服务器上的远程(我将调用它)收集数据,一个在我的本地机器上分析此数据(我将调用它DB_B)。这些表具有基本相同的结构,但在处理端(DB_B)我添加一些列。

所以服务器端(DB_A)看起来像这样:

|UserID|LastActive|InfoA|InfoB|

在本地 ( DB_B) 上是这样的:

|UserID|LastActive|InfoA|InfoB|InfoC|

因此,当我最初将数据导入本地时InfoCNULL然后我处理数据以在InfoC. 与此同时,DB_A用新数据填充和更新。我想要的是从中导出数据DB_A并将其导入DB_B并更新字段,例如LastActive并且InfoB不覆盖InfoC,这样我以后可以处理所有InfoC尚未设置的行

到目前为止我发现了什么:

  • 一个简单的 mysqldump 和 import 不起作用,因为表的结构不同。因此,我使用带有 --execute 和 -X 参数的 mysql 来获取 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 直接执行此操作的方法,因为它似乎只是真正支持IGNOREREPLACE作为选项,这两者都不是真正适合您的目的。

于 2012-10-22T13:25:38.990 回答