【问题标题】:Bulk Import Matching Logic批量导入匹配逻辑
【发布时间】:2014-07-24 02:14:30
【问题描述】:

我有一个每月更新并通过 CSV 文件导出的大型数据集(约 1500 万条记录)。我需要将这些数据匹配并合并到一个包含大致相同数量的实体的数据库中。数据源关于匹配记录的业务规则与我的不同;因此,源文件中可能有匹配的记录(根据我的规则)。

我遇到的问题是匹配的记录通常在 CSV 文件中一行接一行地出现。对于自上次导入以来的任何新数据,除非我在每一行之后都提交,否则在下一次提交之前检查数据库是否匹配将不会返回任何内容,届时该提交中的所有记录(包括那些应该匹配其他记录)将被持久化。

例如,如果我的提交间隔为 50 并且在两次提交之间读取了 30 行匹配的行,则这 30 条记录将被持久化,而不是一条合并记录。

我尝试在每条源记录之后提交,但这会大大减慢导入速度,原因很明显。鉴于数据集的大小,即使是对性能的微小影响也会对整体运行时间产生很大影响。

我唯一能想到的就是跟踪未提交的记录并匹配它们以及数据库中的内容。我正在使用 Spring Data JPA 进行持久性(由 Hibernate 支持)和 Spring Batch 进行导入,如果这有所不同的话。

我觉得我可能缺少一些东西,而且我确信我不是第一个解决这个问题的人。提前感谢您的任何建议。

【问题讨论】:

    标签: java hibernate jpa spring-data spring-batch


    【解决方案1】:

    如果您的数据库支持,您可以使用SQL MERGE 命令。这样您就可以将匹配行问题委托给数据库引擎。

    MERGE INTO tablename USING table_reference ON (condition)
    WHEN MATCHED THEN
    UPDATE SET column1 = value1 [, column2 = value2 ...]
    WHEN NOT MATCHED THEN
    INSERT (column1 [, column2 ...]) VALUES (value1 [, value2 ...
    

    【讨论】:

    • 不幸的是,Postgres 不支持它 - wiki.postgresql.org/wiki/SQL_MERGE
    • 请看this post
    • 感谢您的回复;但是,在这种特殊情况下,对象图中有 38 个属性可以更新。如果我理解正确,实施建议的解决方案将使我创建一个具有 38 个输入参数的函数。此外,我会将业务逻辑放入数据库中,以控制何时允许更新属性——这是我不想做的事情。
    【解决方案2】:

    如何使用 Java 将 csv 文件加载到临时表中。触发存储过程以仅将必要的行从临时表移动到生产表。完成后,让存储过程清理(截断)临时表。

    【讨论】:

    • 相同的匹配逻辑用于通过多种方式导入记录,包括对应用程序的 Web 服务调用。对于像这样一次记录一个的情况,将记录转储到临时表中然后启动存储过程似乎有点过头了。我还想将我的业务逻辑排除在数据库之外,因为它确实应该驻留在应用程序中作为(IMO)正确设计的问题。如果我要使用临时表,我更愿意使用应用程序来匹配记录;但是,这将需要更多次访问(或更多涉及的查询)到数据库。
    猜你喜欢
    • 2013-03-16
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-23
    • 2018-11-18
    • 2016-03-18
    • 2014-07-31
    相关资源
    最近更新 更多