微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PostgreSQL多列独特不起作用

我在Postgresql 9.4中有一个奇怪的情况.
我有一张桌子:

id      integer                 NOT NULL DEFAULT nextval('users_userpropMeta_id_seq'::regclass)
name    character varying(255)  NOT NULL
cls     character varying(4)    NOT NULL
app_id  integer                 NOT NULL

一个独特的约束:
UNIQUE(app_id,名称)

现在我查询表

SELECT COUNT(*),app_id,name FROM users_userpropMeta GROUP BY app_id,name HAVING COUNT(*) > 1;

得到:

count | app_id |          name
-------+--------+-------------------------
     2 |   6019 | Создание серии писем
     2 |   6019 | Увеличение объемов базы
(2 rows)

如此独特不起作用?我进一步说:

SELECT * FROM users_userpropMeta WHERE app_id=6019 AND name in ('Создание серии писем','Увеличение объемов базы');
  id  |          name           | cls | app_id
------+-------------------------+-----+--------
 7308 | Создание серии писем    | str |   6019
 7309 | Увеличение объемов базы | str |   6019
(2 rows)

只有2排.这里有一些魔力.让我们找到带有黑客的行:

SELECT MAX(id),MIN(id),COUNT(*),name HAVING COUNT(*) > 1;

 max  | min  | count | app_id |          name
------+------+-------+--------+-------------------------
 7308 | 4633 |     2 |   6019 | Создание серии писем
 7309 | 4636 |     2 |   6019 | Увеличение объемов базы
(2 rows)

这里有行:

SELECT * FROM users_userpropMeta WHERE id IN (7308,7309,4633,4636);
  id  |          name           | cls | app_id
------+-------------------------+-----+--------
 4633 | Создание серии писем    | str |   6019
 4636 | Увеличение объемов базы | str |   6019
 7308 | Создание серии писем    | str |   6019
 7309 | Увеличение объемов базы | str |   6019
(4 rows)

逐行比较是正确的,它们是相同的:

SELECT a.id,b.id,a.name,b.name,a.name = b.name FROM users_userpropMeta AS a CROSS JOIN users_userpropMeta AS b WHERE a.id IN (7308,4636) AND b.id IN (7308,4636);
  id  |  id  |          name           |          name           | ?column?
------+------+-------------------------+-------------------------+----------
 4633 | 4633 | Создание серии писем    | Создание серии писем    | t
 4633 | 4636 | Создание серии писем    | Увеличение объемов базы | f
 4633 | 7308 | Создание серии писем    | Создание серии писем    | t
 4633 | 7309 | Создание серии писем    | Увеличение объемов базы | f
 4636 | 4633 | Увеличение объемов базы | Создание серии писем    | f
 4636 | 4636 | Увеличение объемов базы | Увеличение объемов базы | t
 4636 | 7308 | Увеличение объемов базы | Создание серии писем    | f
 4636 | 7309 | Увеличение объемов базы | Увеличение объемов базы | t
 7308 | 4633 | Создание серии писем    | Создание серии писем    | t
 7308 | 4636 | Создание серии писем    | Увеличение объемов базы | f
 7308 | 7308 | Создание серии писем    | Создание серии писем    | t
 7308 | 7309 | Создание серии писем    | Увеличение объемов базы | f
 7309 | 4633 | Увеличение объемов базы | Создание серии писем    | f
 7309 | 4636 | Увеличение объемов базы | Увеличение объемов базы | t
 7309 | 7308 | Увеличение объемов базы | Создание серии писем    | f
 7309 | 7309 | Увеличение объемов базы | Увеличение объемов базы | t
(16 rows)

任何人都可以解释,为什么唯一约束插入两行无例外?为什么IN运算符找不到它们(我想到了一些不可打印的符号?),但是相等测试表明它们是相同的?

P. s.最初,我已经使用pglogical创建了Postgresql 9.6订阅,以便从postgres到另一台服务器创建逻辑副本.它失败了,错误,它不能插入重复的行=).

解决方法

这必须是一个损坏的索引.

尝试使用enable_seqscan = off,看看是否仍然找到重复项.

可能你必须通过ctid删除重复的条目并重新索引表.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐