【问题标题】:JDBC/SQLite batch insert with foreign key constraints带有外键约束的 JDBC/SQLite 批量插入
【发布时间】:2013-10-18 00:42:34
【问题描述】:

我正在尝试将数据从 CSV 文件导入数据库,但表 A 具有外键约束表 B。如果外键匹配,我想要将数据插入 A 并更新 B 中的相关行B 中的主键(并且没有其他问题);否则什么都不会发生。目前,我正在执行以下操作(稍微复杂一点的版本):

PRAGMA foreign_keys = ON;

for (row in b.csv){
    INSERT INTO b
    VALUES ("b_key", NULL, NULL);
}

for (row in a.csv){
    INSERT OR IGNORE INTO a 
    VALUES ("a_key", "b_key", ...);

    UPDATE OR IGNORE b 
    SET x = "X", y = "Y"
    WHERE key = "b_key";
}

最终结果是 a.csv 将包含“b_key”不在表 b 中的行,此时整个批量更新将失败,并出现异常“外键约束失败”。任何人都知道我可以让它工作的简单(甚至不简单)方法吗?

【问题讨论】:

  • 为什么数据有无效的b键?为什么不能简单地检查密钥是否存在?
  • 1.因为这是家庭作业的一部分。 2. 为了避免这种情况,我的第一个想法是在执行插入和更新之前执行一个查询,检查 b 中是否存在密钥。这非常慢。我的下一个想法是将所有 b_keys 放入一个哈希集中,并在插入和更新之前检查它们是否存在。这未能防止外键错误。我正在尝试使用该方法解决问题,但似乎仍然应该有更好的方法来做到这一点。
  • 如果您有proper indexes,检查密钥是否存在并不慢(无论如何您都应该拥有它们,因为内置的 FK 检查也需要它们)。您是否对所有更新使用一个事务?

标签: sqlite jdbc foreign-keys bulkinsert


【解决方案1】:

1) 在第二个循环中切换INSERTUPDATE 的顺序。这样,“b”将在“a”需要它之前设置。

2) 使用INSERT OR REPLACE 而不是UPDATE 作为“b”键。更多关于它是如何工作的以及它为什么擅长的:SQLite - UPSERT *not* INSERT or REPLACE。基本上,在将任何内容放入“a”表之前,您将保证您拥有“b”中的键。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-20
    • 2014-01-17
    • 1970-01-01
    • 1970-01-01
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多