从bash批量插入MySQL相关表

时间:2012-04-10 15:48:30

标签: mysql bash

我需要从CSV文件中定期将大量数据上传到MySQL数据库。我通过简单地从bash脚本执行LOAD DATA INFILE来实现这一点。然而,现在,数据将分布在几个表中,并保持关系。在这种情况下,一般策略是什么?

让我们假设一个最初很简单的任务:关系一对多,两个表。

我认为是这样的:

  1. 获得表1的最大识别码
  2. 手动将标识符应用于CSV文件
  3. 将文件拆分为两个目标表
  4. 插入两个表格
  5. 这是最佳解决方案吗? (例如,在实例中,我将以这种方式更新许多多对多关系。)

    我可以在整个过程中将表格1从bash级别锁定吗?或者我是否必须使用一些中间工具(如perl或Python)将所有内容保存在一个会话中?

1 个答案:

答案 0 :(得分:0)

您的问题中表达了各种相互矛盾的要求。这个答案集中在它的“保持锁定”方面。

为了维护整个操作的表锁,您必须保持与sql server的单个连接。一种方法是将所有内容作为多行多命令输入传递给mysql命令行客户端的单个调用。基本上是这样的:

{ echo "LOCK TABLES Table1 WRITE"
  for i in "${infiles[@]}"; do
    echo "LOAD DATA LOCAL INFILE '${i}'"
  done
} | mysql

只要您可以生成所有必需的语句而不保留数据库中的问题(如最大标识符),那么这将有效。

为了混合读取操作(如要求最大值)和写入操作(如加载某些文件的内容),您将与服务器进行双向通信。通过bash实现这一点非常棘手,所以我建议反对它。即使您不需要提问,bash管道提供的单向连接也是一个危险源:如果mysql端出现任何问题,bash将不会注意到并且无论如何都会发出下一个命令。您最终可能会提交不一致的数据。

由于这些原因,我宁愿建议一些可用的mysql绑定的脚本语言,比如你提到的Perl或Pyhon选项。用这些语言读取CVS文件很简单,因此您可以在一个脚本中执行以下所有操作:

  1. 锁定表
  2. 启动交易
  3. 读取输入csv文件
  4. 询问max id
  5. 等问题
  6. 调整输入数据以匹配表格布局
  7. 将数据插入表格
  8. 如果没有发生错误,则提交事务