代码之家  ›  专栏  ›  技术社区  ›  klennepette

应用程序感知数据导入

  •  2
  • klennepette  · 技术社区  · 16 年前

    我正在构建一个将数据导入到sqlserver2008express数据库的应用程序。
    当前正在生产的应用程序正在使用此数据库。
    需要导入的数据来自不同的来源,主要是excel表和xml文件。

    数据库包含以下表:

    • 工具
    • 电动工具
    • 敲击工具
    • 业主

    源文件中的每一行或XML标记都包含有关1个工具的信息:
    名称、工具类型、重量、功率、所有者、材料等…

    这些行中的每一行都有工具所有者的名称此名称必须插入到所有者表中,但前提是该名称不在所有者表中。
    对于这些行中的每一行,都需要在tools表中插入一个新行。
    tools表有一个字段owner\u id,其中owner表的外键需要设置owner表中相应行的主键
    根据工具类型,必须在powertools表或strikingtools表中创建新行。这两个表还有一个tool\u id字段,其中包含必须填写的tools表的外键。
    tools表有一个tool_owner_id字段,其中包含必须填写的owner表的外键。

    如果导入文件中的任何行由于某种原因无法导入,则需要回滚整个导入

    目前我正在使用一个数据集来完成这项工作,但是对于一些大文件(超过200.000个工具),这需要相当多的内存。有人能想出更好的办法吗?

    3 回复  |  直到 16 年前
        1
  •  2
  •   Philip Fourie    16 年前

    有两个主要问题需要解决:

    • 高效地解析大型xml文档。
    • 向数据库中添加大量记录。

    XML解析
    尽管数据集方法有效,但整个xml文档都被加载到内存中。为了提高处理大型XML文档的效率,您可能需要查看 XmlReader 班级。这个api比 DataSet 提供。但是,您将得到一个好处,即不立即将整个dom加载到内存中。

    将记录插入数据库
    为了满足你 Atomicity 要求您可以使用单个数据库事务,但您正在为单个事务处理的大量记录并不理想。您很可能会遇到以下问题:

    • 数据库必须处理大量锁
    • 可能从行锁升级到页锁甚至表锁的数据库锁。
    • 在导入过程中,数据库的并发使用将受到严重影响。

    我建议使用以下方法而不是单个数据库事务:

    • 查看是否可以创建较小的事务批处理。一次大概有100张唱片。也许可以逻辑地将XML文件的部分加载到一起,在这里可以将数据的子集作为一个单元加载到系统中。
    • 尽可能多地预先验证数据。例如,检查所需字段是否已填写或FK是否正确。
    • 使上传可重复。跳过现有数据。
    • 提供手动撤消策略。我知道这说起来容易做起来难,但作为一个附加的业务规则,它甚至可能是必需的。例如,上传成功了,但几个小时后有人意识到上传了错误的文件。

    将数据上载到数据库中的初始暂存区域以执行验证并标记哪些记录已被处理,这可能很有用。

        2
  •  0
  •   Dustin Laine    16 年前

    使用ssis,并创建和etl包。

        3
  •  0
  •   FallenAvatar    16 年前

    使用 Transactions 用于回滚功能和处理创建/检查外键的存储过程。