1

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

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

我认为是这样的:

  1. 获得表 1 的最大标识符
  2. 手动将标识符应用到 CSV 文件
  3. 考虑到两个目标表来拆分文件
  4. 插入两个表

是最优解吗?(例如,在实际情况下,我将通过这种方式更新许多多对多关系。)

我可以在整个过程中从 bash 级别锁定表 1 吗?还是我必须使用 perl 或 Python 之类的中介工具来将所有内容保存在一个会话中?

4

1 回答 1

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. 问最大ID之类的问题
  5. 调整输入数据以匹配表格布局
  6. 向表中插入数据
  7. 如果没有发生错误,则提交事务
于 2012-06-24T21:08:08.353 回答