热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MySQL编码引发的两个问题原荐

先讲一下写该文章的原因,首先,工作中又遇到一条很熟悉的MySQL报错信息对于mysql的字符集编码已经不陌生了,不过,每次遇到相关问题都是依赖于百度、Google今天遇到的emoji表情的存储问题也是司空见惯了,原因多数是因为MySQL使用了utf8字符集(至于公司之前为什么会用utf8我也不清楚,就不过多吐槽了),utf8字符集本身并无可厚非,但是MySQL的这一败笔算是真正的技术打脸,详情可见

概述

先讲一下写该文章的原因,首先,工作中又遇到一条很熟悉的 MySQL 报错信息 Cause: java.sql.SQLException: Incorrect string value:Cause: java.sql.SQLException: Incorrect string value… (emoji表情存储导致),原因是MySQL的字符集导致的;其次,因为一直听说数据库变更可能锁表,但是一直不知道到底哪些操作会导致锁表。所以今天对相关知识做一个系统的整理。

对于mysql的字符集编码已经不陌生了,不过,每次遇到相关问题都是依赖于百度、Google...

今天遇到的emoji表情的存储问题也是司空见惯了,原因多数是因为MySQL使用了utf8字符集(至于公司之前为什么会用utf8我也不清楚,就不过多吐槽了),utf8字符集本身并无可厚非,但是MySQL的这一败笔算是真正的技术打脸,详情可见 《永远不要在MySQL中使用UTF-8》 。

言归正传,今天整理两个问题:

  • 什么是MySQL编码?
  • 什么操作会导致MySQL锁表?

确定要大刀阔斧的干?

遇到上面关于数据库字符集的问题,想必大家会想到两种办法:一,修改编码字符集为utf8mb4;二,找开发对相应的字段进行处理,然后再存入数据库。当然,第一种方法要简单有效的多,这也是大多数情况会采用的方法,这次我们也是采用的第一种方法,于是有了接下来的问题。

修改字段字符集编码:

ALTER TABLE tbl_name CHANGE c_name c_name CHARACTER SET character_name [COLLATE ...];

如:ALTER TABLE logtest CHANGE title title VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

再次插入数据,发现还是报错!why?Google一下,发现这篇文章 彻底解决MySQL字符集问题 。

沿着这个思路,查看公司线上和测试服(能正常写入数据)数据库编码相关配置: MySQL编码引发的两个问题 原 荐

如图所示,线上数据库数据表的编码仍然是utf8!问题的原因浮出水面,那么为什么线上线下会不一致呢?刚来公司不久就不追溯了。那么,改线上数据表的编码类型吧。

此时,另一个问题迎面而来, 更改数据表编码类型会不会导致数据库锁表呢? (话外音:线上数据库,如果锁表,影响还是比较严重的。。。)在此告诫各位看管,线上任何修改一定要三四而后行!

想要解决上面提到的问题,还得从数据库的原理入手,下面做一个系统的学习和整理。

MySQL编码体系——数据存储编码

MySQL的字符编码结构比较细,它大方向分为两个部分:数据存储编码和数据传输编码。本篇讨论数据存储编码部分,数据传输编码详见 MySQL的字符编码体系(二)——数据存储编码 。

编码层次

数据存储的字符编码配置是指定数据库中存储的数据默认采用什么字符编码。默认字符编码的设置分为四个层次:服务器级、数据库级、数据表级和列级。也就是说,可以为服务器设置一个默认字符编码,再为服务器中的每一个数据库设置不同的默认编码,再为同一个数据库中的每一个数据表设置不同的默认编码,再为同一个数据表中的每一个列设置不同的默认编码。

MySQL编码引发的两个问题 原 荐

那这四个层次的编码设置到底如何起作用呢?如果新建数据库时没有指定字符编码,就默认设置为服务器的编码;如果新建数据表时没有指定任何编码,就默认设置为数据库的编码;如果向数据表添加新列或新建数据表时没有特别指定某些列的编码,那么这些列就默认设置为数据表的编码。注意这里四个层次的编码都是作为“默认”的存在,用户创建数据库、表或增加列时直接指定的编码是最优先的。

另一方面,直接改变这四个层次的编码并不会改变它们各自所有下层对象的当前编码。比如修改只Server级,那么所有已经存在的数据库的默认编码不变,数据表、表列以及每一行现有数据记录的字符编码都不变,但是如果新建一个数据库且不指定其默认编码,那它的默认编码就会被设置为Server的默认编码;同样即使修改了所有四个层次的编码,但是数据表中每一条现有记录的字符字段仍然是按原来的编码存储的,但是如果向数据表中新插入一条记录,数据库将根据数据表当前各列的默认编码来存储该条记录的各个字符字段。

参考: MySQL的字符编码体系(一)——数据存储编码

设置方法

修改Server以下 各级编码的 SQL 语句如下:

# 库
ALTER {DATABASE | SCHEMA} [db_name] [DEFAULT] CHARACTER SET [=] charset_name;

# 表
ALTER TABLE dbl_name [DEFAULT] CHARACTER SET [=] charset_name;

# 字段
ALTER TABLE dbl_name MODIFY [COLUMN] col_name {CHAR[(length)] | TEXT} CHARACTER SET charset_name;

注意上面第三条修改列字符编码,实际上是通过完全重新定义列属性的方式实现的,语法跟创建新数据表时指定列字段属性一样的。所以如果这里只是想修改列字符编码,那就必须完整地写上创建该列时使用的所有定义修饰。

修改Server默认编码可以通过运行时直接修改变量character_set_server实现,但这样是临时性的,客户端关闭重启后又会自动恢复。要想永久改变Server默认编码需要在my.ini或my.cnf配置文件的“[mysqld]”区域中设定该变量的值,然后重启服务器:

[mysqld]
character_set_server=charset_name

锁表问题

然后,突然想到另一个问题,上面操作会不会导致数据库锁表呢? 什么操作会导致mysql锁表?

mysql在修改表结构时的风险及解决办法

MySQL 5.7 online ddl的一些改进

mysql5.7 DDL 雷区

修改数据库编码的SQL

最后补充一下修改各个层级编码字符集的SQL:

  • 查看数据库各种编码类型:

    mysql> show variables like 'char%';
  • 修改字段编码:( 不要直接修改,避免锁表,推荐工具:pt-online-schema-change )

    mysql> ALTER TABLE tbl_name CHANGE c_name c_name CHARACTER SET character_name [COLLATE ...];
    
    如:ALTER TABLE logtest CHANGE title title VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
  • 修改数据表编码:

    mysql> ALTER TABLE table_name DEFAULT CHARACTER SET utf8mb4 [COLLATE ...] ;
    
    如:ALTER TABLE table_name DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
  • 修改数据库编码:

    mysql> set  character_set_server = xxx;
    mysql> set character_set_database = xxx;
    
    如:set character_set_database = utf8mb4;

    这样修改,重启数据库后会被还原,如果要永久生效,需要修改数据库配置:

    • vim my.cnf

      # 对本地的mysql客户端的配置
      [client]
      default-character-set = utf8mb4
      
      # 对其他远程连接的mysql客户端的配置
      [mysql]
      default-character-set = utf8mb4
      
      # 本地mysql服务的配置
      [mysqld]
      character-set-client-handshake = FALSE
      character-set-server = utf8mb4
      collation-server = utf8mb4_unicode_ci

      重启mysql生效。

MySQL几个character_set变量的含义

参数 含义
character_set_client 主要用来设置客户端使用的字符集
character_set_connection 主要用来设置连接数据库时的字符集,如果程序中没有指明连接数据库使用的字符集类型则按照这个字符集设置
character_set_database 主要用来设置默认创建数据库的编码格式,如果在创建数据库时没有设置编码格式,就按照这个格式设置
character_set_filesystem 文件系统的编码格式,把操作系统上的文件名转化成此字符集,即把 character_set_client转换character_set_filesystem, 默认binary是不做任何转换的。
character_set_results 数据库给客户端返回时使用的编码格式,如果没有指明,使用服务器默认的编码格式
character_set_server 服务器安装时指定的默认编码格式,这个变量建议由系统自己管理,不要人为定义
character_set_system 数据库系统使用的编码格式,这个值一直是utf8,不需要设置,它是为存储系统元数据的编码格式
character_sets_dir 这个变量是字符集安装的目录

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 我们


推荐阅读
  • Windows7 64位系统安装PLSQL Developer的步骤和注意事项
    本文介绍了在Windows7 64位系统上安装PLSQL Developer的步骤和注意事项。首先下载并安装PLSQL Developer,注意不要安装在默认目录下。然后下载Windows 32位的oracle instant client,并解压到指定路径。最后,按照自己的喜好对解压后的文件进行命名和压缩。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • WhenIusepythontoapplythepymysqlmoduletoaddafieldtoatableinthemysqldatabase,itdo ... [详细]
  • 移动端常用单位——rem的使用方法和注意事项
    本文介绍了移动端常用的单位rem的使用方法和注意事项,包括px、%、em、vw、vh等其他常用单位的比较。同时还介绍了如何通过JS获取视口宽度并动态调整rem的值,以适应不同设备的屏幕大小。此外,还提到了rem目前在移动端的主流地位。 ... [详细]
  • Postgresql备份和恢复的方法及命令行操作步骤
    本文介绍了使用Postgresql进行备份和恢复的方法及命令行操作步骤。通过使用pg_dump命令进行备份,pg_restore命令进行恢复,并设置-h localhost选项,可以完成数据的备份和恢复操作。此外,本文还提供了参考链接以获取更多详细信息。 ... [详细]
  • Todayatworksomeonetriedtoconvincemethat:今天在工作中有人试图说服我:{$obj->getTableInfo()}isfine ... [详细]
  • 微软评估和规划(MAP)的工具包介绍及应用实验手册
    本文介绍了微软评估和规划(MAP)的工具包,该工具包是一个无代理工具,旨在简化和精简通过网络范围内的自动发现和评估IT基础设施在多个方案规划进程。工具包支持库存和使用用于SQL Server和Windows Server迁移评估,以及评估服务器的信息最广泛使用微软的技术。此外,工具包还提供了服务器虚拟化方案,以帮助识别未被充分利用的资源和硬件需要成功巩固服务器使用微软的Hyper - V技术规格。 ... [详细]
  • 花瓣|目标值_Compose 动画边学边做夏日彩虹
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Compose动画边学边做-夏日彩虹相关的知识,希望对你有一定的参考价值。引言Comp ... [详细]
  • 程序员学习数据库安装教程中必会MySQL使用规范手册
    一个平台或系统随着时间的推移和用户量的增多,数据库操作往往会变慢;而在Java应用开发中数据库更是尤为重要,绝大多数情况下数据库的性能决定 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
author-avatar
QJ974
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有