Java Mysql latin1 -- cp1252 West European latin1_swedish_ci 转中文

真TMD操蛋,一个编码问题折磨一周时间,终于找到解决办法,

原文转自:http://www.2cto.com/kf/201202/120875.html

解决如下:

Mysql 的latin1 不等于标准的latin1(iso-8859-1) 和cp1252,比iso-8859-1多了0x80-0x9f字符,比cp1252多了0x81,0x8d,0x8f,0x90,0x9d 一共5个字符。

http://dev.mysql.com/doc/refman/5.0/en/charset-we-sets.html

latin1 is the default character set. MySQL's latin1 is the same as the Windows cp1252 character set. This means it is the same as the official ISO 8859-1 or IANA (Internet Assigned Numbers Authority) latin1, except that IANA latin1 treats the code points between 0x80 and 0x9f as “undefined,” whereas cp1252, and therefore MySQL's latin1, assign characters for those positions. For example, 0x80 is the Euro sign. For the “undefined” entries in cp1252, MySQL translates 0x81 to Unicode 0x0081, 0x8d to 0x008d, 0x8f to 0x008f, 0x90 to 0x0090, and 0x9d to 0x009d.

 

这样在Java中,如果使用标准的iso-8859-1或者cp1252解码可能出现乱码。
s.getBytes("iso-8859-1") 或者 s.getBytes("cp1252");

写了一段代码来解决这个问题

private String convertCharset(String s){
        if(s!=null){
             try {
                 int length = s.length();
                 byte[] buffer = new byte[length];
                 //0x81 to Unicode 0x0081, 0x8d to 0x008d, 0x8f to 0x008f, 0x90 to 0x0090, and 0x9d to 0x009d.
                 for(int i=0;i<length;++i){
                     char c = s.charAt(i);
                     if(c==0x0081){
                         buffer[i]=(byte)0x81;
                     }
                     else if(c==0x008d){
                         buffer[i]=(byte)0x8d;
                     }
                     else if(c==0x008f){
                         buffer[i]=(byte)0x8f;
                     }
                     else if(c==0x0090){
                         buffer[i]=(byte)0x90;
                     }
                     else if(c==0x009d){
                         buffer[i]=(byte)0x9d;
                     }
                     else{
                         buffer[i] = Character.toString(c).getBytes("cp1252")[0];
                     }
                 }
                 String result = new String(buffer,"utf-8");
                 return result;
             } catch (UnsupportedEncodingException e) {
                 logger.error("charset convert error", e);
             }
         }
         return null;
     }


 

摘自 小明思考

 

[SQL] Query information_schema start [ERR] 1044 - Access denied for user 'root'@'%' to database 'information_schema' [ERR] /* Navicat Premium Data Transfer Source Server : localhost_3306 Source Server Type : MySQL Source Server Version : 50648 Source Host : localhost:3306 Source Schema : information_schema Target Server Type : MySQL Target Server Version : 50648 File Encoding : 65001 Date: 31/12/2020 11:49:28 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for CHARACTER_SETS -- ---------------------------- DROP TABLE IF EXISTS `CHARACTER_SETS`; CREATE TABLE `CHARACTER_SETS` ( `CHARACTER_SET_NAME` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', `DEFAULT_COLLATE_NAME` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', `DESCRIPTION` varchar(60) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', `MAXLEN` bigint(3) NOT NULL DEFAULT 0 ) ENGINE = MEMORY CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Fixed; -- ---------------------------- -- Records of CHARACTER_SETS -- ---------------------------- INSERT INTO `CHARACTER_SETS` VALUES ('big5', 'big5_chinese_ci', 'Big5 Traditional Chinese', 2); INSERT INTO `CHARACTER_SETS` VALUES ('dec8', 'dec8_swedish_ci', 'DEC West European', 1); INSERT INTO `CHARACTER_SETS` VALUES ('cp850', 'cp850_general_ci', 'DOS West European', 1); INSERT INTO `CHARACTER_SETS` VALUES ('hp8', 'hp8_english_ci', 'HP West European', 1); INSERT INTO `CHARACTER_SETS` VALUES ('koi8r', 'koi8r_general_ci', 'KOI8-R Relcom Russian', 1); INSERT INTO `CHARACTER_SETS` VALUES ('latin1', 'latin1_swedish_ci', 'cp1252 West European', 1); INSERT INTO `CHARACTER_SETS` VALUES ('latin2', 'latin2_general_ci', 'ISO 8859-2 Central European', 1); INSERT INTO `CHARACTER_SETS` VALUES ('swe7', 'swe7_swedish_ci', '7bit Swedish', 1); INSERT INTO `CHARACTER_SETS` VALUES ('ascii', 'ascii_general_ci', 'US ASCII', 1); INSERT INTO `CHARACTER_SETS` VALUES ('ujis', 'ujis_japanese_ci', 'EUC-JP Japanese', 3); INSERT INTO `CHARACTER_SETS` VALUES ('sjis', 'sjis_japanese_ci', 'Shift-JIS Japanese', 2); INSERT INTO `CHARACTER_SETS` VALUES ('hebrew', 'hebrew_general_ci', 'ISO 8859-8 Hebrew', 1); INSERT INTO `CHARACTER_SETS` VALUES ('tis620', 'tis620_thai_ci', 'TIS620 Thai', 1); INSERT INTO `CHARACTER_SETS` VALUES ('euckr', 'euckr_korean_ci', 'EUC-KR Korean', 2); INSERT INTO `CHARACTER_SETS` VALUES ('koi8u', 'koi8u_general_ci', 'KOI8-U Ukrainian', 1); INSERT INTO `CHARACTER_SETS` VALUES ('gb2312', 'gb2312_chinese_ci', 'GB2312 Simplified Chinese', 2); INSERT INTO `CHARACTER_SETS` VALUES ('greek', 'greek_general_ci', 'ISO 8859-7 Greek', 1); INSERT INTO `CHARACTER_SETS` VALUES ('cp1250', 'cp1250_general_ci', 'Windows Central European', 1); INSERT INTO `CHARACTER_SETS` VALUES ('gbk', 'gbk_chinese_ci', 'GBK Simplified Chinese', 2); INSERT INTO `CHARACTER_SETS` VALUES ('latin5', 'latin5_turkish_ci', 'ISO 8859-9 Turkish', 1); INSERT INTO `CHARACTER_SETS` VALUES ('armscii8', 'armscii8_general_ci', 'ARMSCII-8 Armenian', 1); INSERT INTO `CHARACTER_SETS` VALUES ('utf8', 'utf8_general_ci', 'UTF-8 Unicode', 3); INSERT INTO `CHARACTER_SETS` VALUES ('ucs2', 'ucs2_general_ci', 'UCS-2 Unicode', 2); INSERT INTO `CHARACTER_SETS` VALUES ('cp866', 'cp866_general_ci', 'DOS Russian', 1); INSERT INTO `CHARACTER_SETS` VALUES ('keybcs2', 'keybcs2_general_ci', 'DOS Kamenicky Czech-Slovak', 1); INSERT INTO `CHARACTER_SETS` VALUES ('macce', 'macce_general_ci', 'Mac Central European', 1); INSERT INTO `CHARACTER_SETS` VALUES ('macroman', 'macroman_general_ci', 'Mac West European', 1); INSERT INTO `CHARACTER_SETS` VALUES ('cp852', 'cp852_general_ci', 'DOS Central European', 1); INSERT INTO `CHARACTER_SETS` VALUES ('latin7', 'latin7_general_ci', 'ISO 8859-13 Baltic', 1); INSERT INTO `CHARACTER_SETS` VALUES ('utf8mb4', 'utf8mb4_general_ci', 'UTF-8 Unicode', 4); INSERT INTO `CHARACTER_SETS` VALUES ('cp1251', 'cp1251_general_ci', 'Windows Cyrillic', 1); INSERT INTO `CHARACTER_SETS` VALUES ('utf16', 'utf16_general_ci', 'UTF-16 Unicode', 4); INSERT [SQL] Process terminated 恢复数据库出现这样的错误
05-28
<think> 我们被要求解释SQL语句中'CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL'的含义和使用场景。根据提供的引用和一般SQL知识,我们可以这样分析: 1. **CHARACTER SET latin1**: 指定该列使用的字符集latin1latin1字符集支持西欧语言(如英语、德语、法语等),每个字符占用1个字节。 2. **COLLATE latin1_swedish_ci**: 指定该列的排序规则(collation)。这里使用的是latin1字符集下的swedish_ci(瑞典语,不区分大小写)排序规则。排序规则决定了字符串比较和排序的规则,比如是否区分大小写(ci表示case insensitive,即不区分大小写),是否区分重音等。 3. **DEFAULT NULL**: 表示该列的默认值为NULL,即如果插入数据时没有指定该列的值,则默认设置为NULL。 **使用场景**: - 当创建或修改表结构时,可以为字符串类型的列(如VARCHAR, CHAR, TEXT等)指定字符集和排序规则。 - 例如,在MySQL中,创建表时可以这样使用: ```sql CREATE TABLE example ( id INT, name VARCHAR(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL ); ``` - 如果整个表的默认字符集和排序规则已经是latin1latin1_swedish_ci,那么列级别的指定可以省略。但如果有特殊需求(比如某一列需要不同的字符集或排序规则),则可以在列级别单独指定。 - 使用场景举例: - 当表中大部分列使用一种字符集(如utf8),但某一列需要存储西欧字符且希望节省空间(因为latin1比utf8占用空间小,因为utf8中一个字符可能占用1~3个字节,而latin1固定1个字节)时。 - 当需要按照瑞典语的排序规则进行不区分大小写的排序和比较时(虽然名为swedish,但通常用于西欧语言)。 **注意**:在引用[2]中,我们看到设置字符集相关的语句,如`SET NAMES utf8`,这通常用于设置客户端连接使用的字符集。而列定义中的字符集则定义了该列存储数据时使用的字符集。 另外,引用[3]中提到了在Oracle中查询列类型等信息,但这里我们主要讨论的是MySQL(因为引用[1]和[2]都是关于MySQL的)。在MySQL中,我们可以通过类似`SHOW CREATE TABLE table_name`的语句来查看列的定义,包括字符集和排序规则。 **总结**:这段SQL片段定义了一个使用latin1字符集latin1_swedish_ci排序规则的列,且该列默认值为NULL。它适用于需要存储西欧字符并且希望进行不区分大小写排序和比较的场景。 §§相关问题§§ 1. 如何在MySQL中修改已有列的字符集和排序规则? 2. 除了latin1MySQL还支持哪些常见字符集? 3. 排序规则中的ci和cs分别代表什么? 4. 在什么情况下需要为列单独指定字符集和排序规则? </think>### SQL中`CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL`的含义与使用场景 #### 1. **组件拆解说明** - **`CHARACTER SET latin1`** 指定该列使用`latin1`字符集。`latin1`是ISO-8859-1的别名,支持西欧语言(如英语、德语、法语等),每个字符占用1字节存储空间。适用于存储非特殊字符的文本数据[^1]。 - **`COLLATE latin1_swedish_ci`** 定义字符的排序和比较规则: - `swedish_ci`:基于瑞典语的排序规则(对其他西欧语言兼容)。 - `ci`(Case Insensitive):**不区分大小写**(例如 `'a' = 'A'`)。 - **`DEFAULT NULL`** 若插入数据时未显式指定该列值,则默认设为`NULL`(空值)。 #### 2. **完整含义** 该语句定义了一个使用`latin1`字符集的列: - 存储时:字符按`latin1`编码(1字节/字符)。 - 比较时:不区分大小写,按瑞典语规则排序。 - 无数据时:默认置为`NULL`。 #### 3. **典型使用场景** 1. **存储西欧语言数据** 当表需要存储英文、德文等文本(无中文、阿拉伯文等),且需节省存储空间时(`latin1`比`utf8`更紧凑)[^1]。 2. **大小写不敏感的查询** 例如用户名字段,需忽略大小写匹配: ```sql SELECT * FROM users WHERE username = 'Admin'; -- 会匹配 'admin', 'ADMIN' 等 ``` 3. **兼容旧系统** 迁移遗留系统时,若原数据采用`latin1`编码,需保持字符集一致。 4. **默认空值约束** 允许字段为空且无默认值(如可选填的中间名字段): ```sql CREATE TABLE users ( middle_name VARCHAR(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL -- 允许不填写 ); ``` #### 4. **注意事项** - **字符集兼容性**:`latin1`不支持中文/日文等非西欧字符,需改用`utf8mb4`。 - **性能影响**:`ci`(不区分大小写)的排序规则可能比`cs`(区分大小写)略慢[^1]。 - **空值处理**:若字段需强制填写,应移除`DEFAULT NULL`并添加`NOT NULL`约束。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值