MySQL 混合字符集和排序规则
MySQL mixing Charset & Collations
我在这个论坛上阅读了不同的文章和主题,以帮助我为我的数据库设置字符集和排序规则。不确定我所做的选择。如果有任何意见或建议,我将不胜感激。
我正在使用 MySQL 5.5.
数据库(与PHP一起使用)将有一些来自不同语言(中文、法语、荷兰语、美国、西班牙语、阿拉伯语等)的数据。
我将主要插入数据并从 table ID'S 获取信息。我不需要完整搜索和比较文本。
所以这是我创建数据库的方法,我决定使用 CHARSET utf8mb4
和 COLLATION utf8mb4_unicode_ci
ALTER DATABASE testDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
当我创建 table:
CREATE TABLE IF NOT EXISTS sector (
idSector INT(5) NOT NULL AUTO_INCREMENT,
sectoreName VARCHAR(45) NOT NULL DEFAULT '',
PRIMARY KEY (idSector)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=0;
对于某些 table,我认为使用 utf8_bin
更好
例如:时区(包含 168 047 行)
CREATE TABLE timezone (
zone_id int(10) NOT NULL,
abbreviation varchar(6) COLLATE utf8_bin NOT NULL,
time_start decimal(11,0) NOT NULL,
gmt_offset int(11) NOT NULL,
dst char(1) COLLATE utf8_bin NOT NULL,
KEY idx_zone_id (zone_id),
KEY idx_time_start (time_start)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=0;
所以基本上我想知道我是否正确,或者我是否正在做一些可能导致问题的事情。
您为 sectoreName
专栏做出了不错的选择。请注意一件事:utf8mb4_unicode_ci
是大多数语言的良好排序规则。但是,对于西班牙语,它的字母表是错误的:在该语言中 N
和 Ñ
被认为是不同的字母。 Ñ
在整理顺序中紧跟在 N
之后。但在其他欧洲语言中,它们被认为是同一个字母。因此,当您的西班牙语用户请求 Niña
时,他们会返回 Niña
和 Nina
。这在他们看来可能是个错误。 (但是,他们可能习惯于从泛欧软件应用程序中获取此类内容。)
您应该在所有新应用程序中使用 utf8mb4
作为您的字符集。因此,在 timezone
table 中使用它而不是 utf8
。对 abbreviation
列使用 _bin
归类就可以了。
不同的列可以有不同的字符集 and/or 排序规则,但是...
- 如果比较不同字符集 或 排序规则 (
WHERE a.x = b.y
) 的列,则无法使用索引。
utf8
不处理所有中文,也不处理部分Emoji。对于那些,你需要 utf8mb4.
关于其他问题...
- 在
INT(5)
中,(5)
没有任何意义。查看范围为 0..65535. 的 SMALLINT UNSIGNED
time_start decimal(11,0)
一时奇怪。如果它是 unix 时间戳,TIMESTAMP
或 INT UNSIGNED
都应该可以正常工作。另见 TIME
.
dst char(1) COLLATE utf8_bin
-- 这需要 3 个字节,因为是 utf8。也许你想要 CHARACTER SET ascii
所以它只有 1 个字节?
- 确实应该给 InnoDB 表一个明确的
PRIMARY KEY
。 (大概zone_id
?)
我在这个论坛上阅读了不同的文章和主题,以帮助我为我的数据库设置字符集和排序规则。不确定我所做的选择。如果有任何意见或建议,我将不胜感激。
我正在使用 MySQL 5.5.
数据库(与PHP一起使用)将有一些来自不同语言(中文、法语、荷兰语、美国、西班牙语、阿拉伯语等)的数据。 我将主要插入数据并从 table ID'S 获取信息。我不需要完整搜索和比较文本。
所以这是我创建数据库的方法,我决定使用 CHARSET utf8mb4
和 COLLATION utf8mb4_unicode_ci
ALTER DATABASE testDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
当我创建 table:
CREATE TABLE IF NOT EXISTS sector (
idSector INT(5) NOT NULL AUTO_INCREMENT,
sectoreName VARCHAR(45) NOT NULL DEFAULT '',
PRIMARY KEY (idSector)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=0;
对于某些 table,我认为使用 utf8_bin
更好
例如:时区(包含 168 047 行)
CREATE TABLE timezone (
zone_id int(10) NOT NULL,
abbreviation varchar(6) COLLATE utf8_bin NOT NULL,
time_start decimal(11,0) NOT NULL,
gmt_offset int(11) NOT NULL,
dst char(1) COLLATE utf8_bin NOT NULL,
KEY idx_zone_id (zone_id),
KEY idx_time_start (time_start)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=0;
所以基本上我想知道我是否正确,或者我是否正在做一些可能导致问题的事情。
您为 sectoreName
专栏做出了不错的选择。请注意一件事:utf8mb4_unicode_ci
是大多数语言的良好排序规则。但是,对于西班牙语,它的字母表是错误的:在该语言中 N
和 Ñ
被认为是不同的字母。 Ñ
在整理顺序中紧跟在 N
之后。但在其他欧洲语言中,它们被认为是同一个字母。因此,当您的西班牙语用户请求 Niña
时,他们会返回 Niña
和 Nina
。这在他们看来可能是个错误。 (但是,他们可能习惯于从泛欧软件应用程序中获取此类内容。)
您应该在所有新应用程序中使用 utf8mb4
作为您的字符集。因此,在 timezone
table 中使用它而不是 utf8
。对 abbreviation
列使用 _bin
归类就可以了。
不同的列可以有不同的字符集 and/or 排序规则,但是...
- 如果比较不同字符集 或 排序规则 (
WHERE a.x = b.y
) 的列,则无法使用索引。 utf8
不处理所有中文,也不处理部分Emoji。对于那些,你需要 utf8mb4.
关于其他问题...
- 在
INT(5)
中,(5)
没有任何意义。查看范围为 0..65535. 的 time_start decimal(11,0)
一时奇怪。如果它是 unix 时间戳,TIMESTAMP
或INT UNSIGNED
都应该可以正常工作。另见TIME
.dst char(1) COLLATE utf8_bin
-- 这需要 3 个字节,因为是 utf8。也许你想要CHARACTER SET ascii
所以它只有 1 个字节?- 确实应该给 InnoDB 表一个明确的
PRIMARY KEY
。 (大概zone_id
?)
SMALLINT UNSIGNED