mysql不支持范围U + 0000..U + FFFF中的所有符号

时间:2014-06-27 14:12:17

标签: mysql unicode utf-8

考虑下表:

CREATE TABLE t1 (f1 VARCHAR(255));

然后,不管ruby

#!/usr/bin/env ruby
require 'json'
require 'sequel'
require 'mysql2'
DB = Sequel.connect(
    :adapter => 'mysql2',
    :database => 'd1',
    :user => '<user>',
    :password => '<password>',
    :encoding => 'utf8')
v1 = '{"a":"b\ud83c\udf4ec"}'
v2 = JSON.parse(v1)
p v2['a']
DB[:t1].truncate
DB[:t1].insert(f1: v2['a']);
p DB[:t1].first[:f1]

php

#!/usr/bin/env php
<?php
$dbh = new PDO('mysql:dbname=d1', '<user>', '<password>', [
    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$dbh->exec('TRUNCATE TABLE t1');
$v1 = '{"a":"b\ud83c\udf4ec"}';
$v2 = json_decode($v1);
var_dump($v2->a);
$sth = $dbh->prepare("INSERT INTO t1 VALUES (?)");
$sth->execute([$v2->a]);
$sth = $dbh->query("SELECT * FROM t1");
var_dump($sth->fetch()['f1']);

数据库中的内容是b。我正在运行mysql-5.1和文档says

  

MySQL 5.1支持两个用于存储Unicode数据的字符集:

     
      
  • ucs2,Unicode字符集的UCS-2编码,每个字符使用16位。

  •   
  • utf8,Unicode字符集的UTF-8编码,每个字符使用一到三个字节。

  •   
     

这两个字符集支持Unicode 3.0版的基本多语言平面(BMP)中的字符。 BMP字符具有以下特征:

     
      
  • 他们的代码值介于0到65535之间(或U+0000 .. U+FFFF)。
  •   

我做错了什么?

UPD

$ mysql -BNe 'SHOW CREATE TABLE t1' d1
t1  CREATE TABLE `t1` (\n  `f1` varchar(255) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8

2 个答案:

答案 0 :(得分:1)

看来这两个转义序列只代表一个字符:RED APPLE (U+1F34E)。第一个是代理人。 surrogates are

  

UCS使用代理来处理初始基本多语言平面之外的字符,而不需要使用超过16位的字节表示。

所以必须如此,结果字符在BMP之外。并且mysql的{​​{1}}字符集不支持。

答案 1 :(得分:0)

在我的MySQL 5.1(来自debian)中做

CREATE TABLE t1 (f1 VARCHAR(255));

有效地创建了一个LATIN1表:

mysql> show CREATE TABLE t1 ;
+-------+---------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                |
+-------+---------------------------------------------------------------------------------------------+
| t1    | CREATE TABLE `t1` (
  `f1` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+---------------------------------------------------------------------------------------------+

因此,请先检查您的MySQL是否真的默认为UTF-8。

然后,众所周知,MySQL无法存储BMP表中的每个字符。我没有找到关于这方面的参考资料,但是之前就已经看过了。

从mysql 5.5.3引入了一个新的utf8mb4全unicode支持字符集作为statu如下所述:https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-upgrading.html

最后,即使BMP ,它们介于0和0xFFFF之间,也并不意味着他们正在使用此处所述的所有:{{3} }