将旧文本数据库转换为SQL

时间:2013-03-05 21:37:54

标签: mysql sql database text-processing legacy-database

在我的办公室,我们有一个遗留的会计系统,它将所有数据存储在具有固定宽度记录的纯文本文件(TXT扩展名)中。每个数据文件都被命名为例如FILESALE.TXT。我的目标是将这些数据导入MySQL服务器,以供许多其他无法与传统软件连接的程序进行只读使用。每个文件基本上都是一个表。

我需要访问大约20个文件,大约1GB的总数据。每行可能是350-400个字符宽,有30-40列。拉入数据后,没有MySQL表比100mb大得多。

旧版会计系统可以修改文本文件中的任何行,删除旧行(它有一个已删除的记录标记 - 0x7F),并随时添加新行。

几年来,我每隔5分钟就开始一次cron工作:

  1. 检查每个数据文件的最后修改时间。
  2. 如果未修改文件,请跳过它。否则:
  3. 解析数据文件,清除所有问题(仅限非常简单的检查),然后吐出一个制表符分隔的文件,列出我需要的列(我忽略的一些列)。
  4. TRUNCATE表并将新数据导入我们的MySQL服务器,如下所示:

    START TRANSACTION;
    TRUNCATE legacy_sales;
    LOAD DATA INFILE '/tmp/filesale.data' INTO TABLE legacy_sales;
    COMMIT;
    
  5. cron脚本运行每个文件检查并行并行解析,因此整个更新过程实际上并不需要很长时间。最大的表(不经常更改)需要大约30秒才能更新,但大多数表只需不到5秒。

    这一直运作正常,但有一些问题。我想它与数据库缓存混淆,所以每次我必须TRUNCATE和LOAD一个表,其他使用MySQL数据库的程序起初很慢。此外,当我切换到并行运行更新时,数据库可能会处于稍微不一致的状态几秒钟。

    整个过程看起来非常低效!有没有更好的方法来解决这个问题?关于可能值得调查的优化或程序的任何想法?任何面临类似情况的人都有任何巧妙的伎俩吗?

    谢谢!

3 个答案:

答案 0 :(得分:2)

一些想法:

  • 如果文本文件中的行具有修改时间戳,则可以更新脚本以跟踪其运行时间,然后仅处理自上次运行以来已修改的记录。

  • 如果文本文件中的行有一个可以充当主键的字段,则可以为该行维护指纹缓存,并以该ID为键。使用此选项可以检测行何时更改,并跳过未更改的行。即,在读取文本文件的循环中,计算整行的SHA1(或其他)散列,然后将其与缓存中的散列进行比较。如果它们匹配,则行没有改变,所以跳过它。否则,更新/插入MySQL记录并将新哈希值存储在缓存中。缓存可以是GDBM文件,memcached服务器,MySQL表中的指纹字段等等。这将使未更改的行保持不变(因此仍然缓存)在MySQL上。

  • 在交易中执行更新以避免不一致。

答案 1 :(得分:0)

有两件事情浮现在脑海中,我不会详细介绍,但可以随意提问:

  1. 将文件处理卸载到应用程序服务器然后只填充mySQL表的服务,您甚至可以通过检查重复记录来构建智能,而不是截断整个表。

  2. 将处理卸载到另一台mysql服务器并复制/传输。

答案 2 :(得分:0)

我同意亚历克斯的提示。如果可以,只更新已修改的字段和批量更新,并将事务和多个插入分组。交易的另一个好处是更快的更新

如果您担心停机时间而不是截断表格,请插入新表格。然后重命名。

为了提高性能,请确保您对字段进行了适当的索引。

查看数据库特定的性能提示,例如 mysql中的_ delayed_inserts可以提高性能 _缓存可以优化 _即使您没有唯一的行,您也可以(或可能不)能够md5行