Postgresql 唯一约束之谜似乎不适用于批量插入

问题描述 投票:0回答:2

我有一个表,该表具有超过 5 列的唯一约束,全部可为 null=false。这些列是 varchar(30)、varchar、3 个 float8 列。有一个自动增量 id 列,但它不包含在约束中。

我经常有重复项,因此我的查询有“...冲突时不执行任何操作”。我已经看到批量插入的行我知道有所有重复项,所以我预计有 0 个受影响的行。相反,我插入了一些骗局(据我所知,大约是 5-15%,它不是恒定的)。

在此之后,我使用仅在约束中的所有列上进行不同的选择来查询表,并且 postgres 将返回具有重复值的重复行。对于约束中所有列上使用 GROUP BY 的选择查询也是如此。我希望重复的行会合并为一行,但相反,我看到两个重复的行都返回给我。

但是,当我手动删除两个重复行之一,然后尝试插入单个重复行时,postgresql 会正确地告诉我存在冲突,我将无法插入。

我错过了什么吗?我的代码现在调整为逐行插入,但当然效率低很多。

postgresql unique-constraint
2个回答
1
投票

您对

GROUP BY
DISTINCT
的实验证明这些行并不完全相同。我可以想到两个可能的原因:

  1. double precision
    看起来相同(所有有效数字),但实际上并非如此。对浮点数进行相等比较总是很成问题。尝试设置
    extra_float_digits = 3
    ,看看您是否能发现差异。

  2. 有些字符串看起来相等,但其实不然。常见的示例有

     
    (空格)和
     
    (不间断空格)、
    M
    (ASCII 字母)和
    Μ
    (希腊大写字母 Mu)或
    ä
    (分音符)和
    (a 和组合分音符 — 两个代码点一起形成一个字符)。

我的钱在1.


0
投票
  1. 检查文本值时使用
    quote_literal()
    ascii()
    md5()
    sha256(v::bytea)
    演示
    select v,quote_literal(v),ascii(v),md5(v),sha256(v::bytea) 
    from (values 
      (''   ),
      (' '  ),
      (E'\t')) AS _(v);
    
    v quote_literal ascii md5 sha256
    '' 0 d41d8cd98f00b204e9800998ecf8427e \xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
    '' 32 7215ee9c7d9dc229d2921a40e899ec5f \x36a9e7f1c95b82ffb99743e0c5c4ce95d83c9a430aac59f84ef3cbfab6145068
    '' 9 5e732a1878be2342dbfeff5fe3ca5aa3 \x2b4c342f5433ebe591a1da77e013d1b72475562d48578dca8b84bac6651c3cb9
  2. 确保您的浮动相等,而不仅仅是看起来相等。
  3. 如果这些确实是重复的,请清理它们并
    reindex table
    以防索引损坏。
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.