在mysql中导入数据而不覆盖某些列

时间:2012-10-22 12:47:19

标签: mysql mysqldump

好的,我一直坐在这个问题上,我找到了一些解决方法,但我想知道是否有可能按照我的想法去做。

我有2个数据库,一个远程(我将称之为DB_A)在收集数据的网络服务器上,一个在我的本地机器上分析这些数据(我将其称为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_B并更新LastActiveInfoB等字段而不覆盖InfoC以便我以后可以处理没有InfoC设置的所有行

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

  • 一个简单的mysqldump和import不起作用,因为表的结构是不同的。因此,我使用带有--execute和-X参数的mysql来获取XML数据文件
  • 当我使用时,导入DB_B上的XML文件时没有错误: 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;

1 个答案:

答案 0 :(得分:1)

使用INSERT可能是这样做的方式,类似于以下内容,使用“ON DUPLICATE KEY UPDATE”(链接到docs: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作为选项,这两者都不是真的适合你的目的。