对类似字符的唯一约束违规

时间:2018-02-01 14:36:08

标签: mysql postgresql mariadb special-characters collation

我在MariaDB中遇到主键问题(我希望它与MySQL相同)。我正在构建一个Django应用程序,其中一些重要的表由Django创建,并带有以下SQL:

CREATE TABLE table_name
(
  term     VARCHAR(64) NOT NULL PRIMARY KEY,
  enabled  TINYINT(1)  NOT NULL,
  added    DATE        NOT NULL,
  verified DATE        NOT NULL
) ENGINE = InnoDB;

如果我在此表中插入两行,其中termó为第一行,而o为另一行,则会收到错误[23000][1062] Duplicate entry 'o' for key 'PRIMARY'。其他类似字母也会出现相同的行为,例如eé。 我觉得这个行为很奇怪,因为SQLite没有问题。

现在的问题是:如何让数据库引擎将它们视为不同的值?

奖金问题:我可以期待PostgreSQL中的相同行为吗?

已经在SQL中尝试了这个,而不仅仅是Django。

1 个答案:

答案 0 :(得分:1)

嗯,碰巧,我在写这个问题时自己回答了这个问题。我意识到我没有尝试过字符集utf8mb4和排序规则utf8mb4_bin的组合,我记得_bin排序规则比较二进制级别的字符,没有任何规则类似的人物似乎相似。所以用

创建我的数据库
CREATE DATABASE [database_name] CHARACTER SET = 'utf8mb4' COLLATE = 'utf8mb4_bin';

做了这个伎俩。或者,我可以使用

创建每个表
CREATE TABLE [table_name] CHARACTER SET = 'utf8mb4' COLLATE = 'utf8mb4_bin';

,但是在数据库上设置它是唯一可行的选择,因为Django负责创建表。

<强>更新

关于奖金问题,简短回答是:否。

有关详细信息,请参阅下面的nick-barnes评论。

更新2:

Microsoft SQL Server(在SQL Server 2017 CU3上测试)使用排序规则来比较字符串是否相等,因此需要使用二进制排序规则(例如Latin1_General_BIN)来解决此服务器上的此问题。