【问题标题】:Postgresql duplicate primary string keyPostgresql重复主字符串键
【发布时间】:2026-01-14 03:20:03
【问题描述】:

我正面临一种我无法解释的奇怪行为。

我正在使用:

PostgreSQL 13.3 (Debian 13.3-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit

问题:

我有一张这样的桌子

create table symbols
(
    symbol varchar(20) not null
        constraint symbols_pkey
            primary key,
    name varchar(255) not null,
);

所以 symbols.symbol 实际上是一个唯一的主键。 但是当我尝试在该符号上添加外键时,我的程序失败了。它告诉我,该表中不存在值“c3”。

我手动检查了

SELECT * FROM symbols WHERE symbol = 'c3'

它确实不存在,但我的代码告诉我它存在!

几个小时后,我意识到,我只能通过以下方式找到符号

SELECT * FROM symbols WHERE symbol ilike 'c3'

返回:

symbol, name
c3,     c3

我认为我在清理输入数据时犯了一个错误,所以我尝试通过我的 IDE 使用干净的密钥创建一个新项目。 但在那之后,我得到了两个元组:

symbol, name
c3,     c3
c3,     c3-new

SELECT * FROM symbols WHERE symbol = 'c3'

仍然没有返回任何元组。

我检查了排序规则是否正确以及字符串长度是否正确。

select symbol,length(symbol),ascii(symbol) from symbols where symbol ilike 'c3';

元组:

symbol, length, ascii
c3,     2,      99
c3,     2,      99

比我直接用 Postgresql 命令创建另一个项目(没有程序代码,也没有涉及的 IDE),只是简单的 SQL:

insert into symbols values('c3', 'c3-newest');

现在我得到了 3 个元组:

symbol, name
c3,     c3
c3,     c3-new
c3,     c3-newest

这里的主键约束仍然没有生效。 但是当我尝试创建一个新项目时,我得到了:

ERROR: duplicate key value violates unique constraint "symbols_pkey" Detail: Key (symbol)=(c3) already exists.

我的问题:

  • 这里发生了什么?这 3 个“c3”字符串之间的区别在哪里?我如何防止这种情况发生?
  • 我缺少一些关于 varchar 排序规则的基础知识?
  • 是否存在一些 Postgresql 主键错误?

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    我做了一个

    REINDEX TABLE symbols
    

    解决了问题!

    我也从 Docker 映像 postgresql:alpine 切换到 postgresql:13,因为我听说这可能会引发奇怪的问题。

    【讨论】: