【问题标题】:Inserting UTF8 Names to Table gives a Duplicate Error将 UTF8 名称插入表会出现重复错误
【发布时间】:2018-07-19 16:08:19
【问题描述】:

我有以下两个名称的数组:

$x = ['Rodriguez', 'Rodríguez'];

现在,我要做的是将这些值插入到我的表中,如下所示

Collation: utf8mb4_unicode_520_ci
Engine: InnoDB
[id(primary_ai)  -  name(unique)]

我确实使用以下方式连接到数据库:

<?php 
try {
    $pdo = new PDO("mysql:host=localhost;dbname=database;charset=utf8mb4;", 'root', 'root', [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES => false
    ]);
} catch (PDOException $e) {
    echo "Connection failed: " . $e->getMessage();
}

我尝试像这样插入

$paras = $x
$pdo->prepare("INSERT INTO names (name) VALUES (?), (?)")->execute($paras);

但我不断收到错误

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'Rodríguez' for key 'name'

我该如何准确处理这个编码问题?

我尝试使用utf8_encode(),但第二个名称更改为Rodríguez,然后尝试utf8_decode(),但得到Rodr�guez,然后尝试添加PDO::MYSQL_ATTR_INIT_COMMAND =&gt; "SET NAMES 'utf8'",但也没有解决重复错误。

【问题讨论】:

  • 如您所见,编码/解码函数可能会使事情变得更糟。这两个名字拼写不同;一个有一个普通的字母i,另一个有一个精确的 i (í)。但是排序规则说两个 i 都被平等对待。

标签: php mysql pdo character-encoding


【解决方案1】:

MySQL 将 Rodriguez 和 Rodríguez 视为同一件事,您必须更改排序规则。

您可以使用以下方法修复排序规则:

CREATE TABLE Table (...) COLLATE utf8_bin;

【讨论】:

  • 使用utf8_binutf8mb4_binutf8mb4_unicode_520_ci有什么优缺点,
  • 这将导致甚至大写有所作为。希望没问题。
  • @RickJames 这是否意味着最好在需要精确度的列上使用utf8mb4_bin collation,例如usernameprivate keys,或者在某些情况下email,但utf8mb4_unicode_520_ci 更适合将使用 LIKEWHERE 搜索的列以简化对 user 的使用,因为它的 case insensitivity?
  • 排序规则针对流畅的文本。对于用户名,您希望abcAbc 相同还是不同?您可能确实希望密码完全敏感,因此需要utf8mb4_bin 甚至BINARY。电子邮件不区分大小写吗?但这与口音有关吗?
【解决方案2】:

您需要从数据库中删除唯一限制,否则有一些其他编码可以识别 i 和 í 之间的差异。

这可能有效https://www.w3schools.com/html/html_entities.asp

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多