来自 Impala 文档:
在大多数关系数据库中,如果您尝试插入已经插入的行,则插入将失败,因为主键会重复。然而,Impala不会使查询失败。相反,它将生成警告,但继续执行插入语句的其余部分。
为什么 Impala/Kudu 会那样做?请注意,插入不会更新值(有一个 upsert 命令),它只会默默地失败。
有没有办法知道我正在插入重复的主键?
来自 Impala 文档:
在大多数关系数据库中,如果您尝试插入已经插入的行,则插入将失败,因为主键会重复。然而,Impala不会使查询失败。相反,它将生成警告,但继续执行插入语句的其余部分。
为什么 Impala/Kudu 会那样做?请注意,插入不会更新值(有一个 upsert 命令),它只会默默地失败。
有没有办法知道我正在插入重复的主键?
这是因为 kudu 本身不会抛出任何异常(只会引发警告),因此 impala 将(正确地)假设任务成功。
至于Kudu为什么会选择这样做,我们只能猜测。
这只是我的看法。Kudu(和 Impala)专为分析工作负载而不是事务工作负载而设计。这通常涉及大量数据的批处理。由于具有重复键的少量记录而导致应用程序失败是不可取的。
因此,默认行为插入具有非重复键的所有记录并跳过所有重复键。这可以通过使用upsert
which replaces replaces 来改变。
如果 INSERT 语句尝试插入与现有行具有相同主键列值的行,则该行将被丢弃并继续插入操作。当由于重复的主键而丢弃行时,语句以警告结束,而不是错误。(这是 Kudu 早期版本的一个变化,默认情况下在这种情况下返回错误,并且语法 INSERT IGNORE 需要使语句成功。IGNORE 子句不再是 INSERT 语法的一部分。)
对于您更喜欢用重复的主键值替换行而不是丢弃新数据的情况,您可以使用 UPSERT 语句而不是 INSERT。UPSERT 插入全新的行,对于与表中现有主键匹配的行,更新非主键列以反映“更新”数据中的值。
如果您确实想要存储新行,而不是替换现有行,但由于主键唯一性约束而无法这样做,请考虑使用包含在主键中的其他列重新创建表。