复合唯一约束在没有值时给出错误(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 在数据库中可用。我有以下问题:
- 插入是用值 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 编码的字符串进行编码。
我有一个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 在数据库中可用。我有以下问题:
- 插入是用值 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 编码的字符串进行编码。