mysql - 将旧文本数据库转换为 SQL

标签 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. 截断表并将新数据导入到我们的 MySQL 服务器中,如下所示:

    START TRANSACTION;
    TRUNCATE legacy_sales;
    LOAD DATA INFILE '/tmp/filesale.data' INTO TABLE legacy_sales;
    COMMIT;
    

cron 脚本并行运行每个文件检查和解析,因此整个更新过程并不需要很长时间。最大的表(不经常更改)需要大约 30 秒来更新,但大多数表需要不到 5 秒。

这一切运行正常,但存在一些问题。我猜它会扰乱数据库缓存,所以每次我必须截断并加载表时,其他使用 MySQL 数据库的程序一开始都会很慢。此外,当我切换到并行运行更新时,数据库可能会在几秒钟内处于稍微不一致的状态。

整个过程看起来效率极低!有没有更好的方法来解决这个问题?关于可能值得研究的优化或程序有什么想法吗?遇到类似情况的人有什么巧妙的技巧吗?

谢谢!

最佳答案

几个想法:

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

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

  • 在事务内执行更新以避免不一致。

关于mysql - 将旧文本数据库转换为 SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15234632/

相关文章:

javascript - 如何使用 Codeigniter 从数据库调用图像?

AS 的 SQL 语法错误

sql - 删除表上引用自身的所有子项

python - 您将如何为这种数据库关系建模?

php - MySQL 查询数据到 PHP 变量中

mysql - 为什么 MySQL 查询不能正确插入 BIT(50) 位域

php - 当用户对表的输入可以任意组合时,如何构建 SQL 语句?

sql - 是否可以在 postgreSQL 中按子字符串排序?

sql - 无法将类型 System.Data.Entity.DbSet<DataGridSQLExample.Product> 隐式转换为 System.Data.Objects.ObjectQuery<DataGridSQLExample.Product>

database - 将 csv 文件数据加载到表中