复合唯一约束在没有值时给出错误(utf8 字符串被截断)

Composite unique constraint giving error when no value is present (utf8 string truncated)

我有一个table即"tags"。其结构如下:

CREATE TABLE `tags` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8_bin NOT NULL,
  `value` varchar(255) COLLATE utf8_bin NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  UNIQUE KEY `tags_name_value_unique` (`name`,`value`),
  KEY `tags_name_index` (`name`),
  KEY `tags_value_index` (`value`)
  ) ENGINE=InnoDB AUTO_INCREMENT=1380 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

获取不同值的相似错误。错误频繁但随机

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'screen_name-Erika S' for key 'tags_name_value_unique' (SQL: insert into tags (name, value, updated_at, created_at) values (screen_name, Erika Söll, 2018-08-29 08:21:55, 2018-08-29 08:21:55))

在这种情况下,值 Erika Söll 在数据库中不存在,而值 Erika S 在数据库中可用。我有以下问题:

选择和插入值的查询如下:

select * from标签where (名称= 'screen_name' and= 'Klaudia-Krauß') limit 1

insert into标签(名称,,updated_at,created_at) values ('screen_name', 'Klaudia-Krauß', '2018-09-03 04:08:46', '2018-09-03 04:08:46')

插入 table 时,"Erika Söll" 被截断为 "Erika S",即第一个重音字母之前。这是一个字符集问题。更多讨论 ,至:

  • 要存储的字节未编码为utf8。解决这个问题。
  • 另外,检查读取时的连接是否为utf8

不知道您是否使用 PHP、Java、Python 等,我不能更具体。不过可能会有提示 here .

同时,可能你根本不需要id,4个索引可以简化为两个:

PRIMARY KEY(`name`,`value`),
KEY `tags_value_index` (`value`)

我遇到了 PHP 和 MySQL 组合的问题。该问题与数据编码有关。我收到的数据是 UTF8 和其他编码的混合,即在我的例子中是 ISO-8859-1。所以作为修复,我写了下面的代码解决了我的问题

public static function convertToUTF8($input)
{
    return !mb_check_encoding($input, 'UTF-8') ? utf8_encode($input) : $input;
}

mb_check_encoding($input, 'UTF-8') 检查是为了避免对已经采用 UTF8 编码的字符串进行编码。