nodejs和C语言插入mysql数据库乱码问题的解决方法


Posted in NodeJs onApril 14, 2017

在这里记录了nodejs过程中的一些乱码情况,这里的乱码主要是由于网页的编码方式与nodejs的默认解码方式(utf8)不一致所造成的。这一次要说一下的是在C语言和nodejs与MySQL进行交互的时候出现的乱码问题。

       1,由于爬虫程序在多个Docker中执行,因此我需要定期的同步每一个docker中的mysql数据到一个全局的mysql数据表中。使用nodejs进行数据同步,出现中文乱码。要知道在每一docker中的中文是不存在乱码的。原因是nodejs默认处理字符是utf8,而mysql默认是latin1,毕竟是欧洲人开发的数据库。分析如下

       命令show variables like 'char%';得到的结果如下:

+--------------------------+----------------------------+
| Variable_name | Value  |
+--------------------------+----------------------------+
| character_set_client | latin1  |
| character_set_connection | latin1  |
| character_set_database | latin1  |
| character_set_filesystem | binary  |
| character_set_results | latin1  |
| character_set_server | latin1  |
| character_set_system | latin1  |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

       即在建立数据库的时候不特别指定,则数据库,数据表的以及数据字段的编码格式为默认值,而默认值在不更改配置文件的时候是latin1(默认安装形式)。由于utf8是较为通用的编码方式,因此我们将数据库的所有编码方式改为utf8。这里需要说明的是mysql的编码分为好几个层次,包括数据库级别,数据表级别以及数据字段级别等,我这里没有去深究这些方面,一个个去设置每个字段,每个表的编码方式,而是把所有的编码方式均设置为utf8。具体如下: 

      vi /etc/my.cnf修改my.cnf文件如下:

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
default-character-set = utf8
character_set_server = utf8
[mysql]
default-character-set = utf8
[mysql.server]
default-character-set = utf8
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
default-character-set = utf8
[client]
default-character-set = utf8

       修改完之后,重起mysql服务service mysqld restart

       命令show variables like 'char%';再次查看编码格式,得到的结果如下:

+--------------------------+----------------------------+
| Variable_name | Value  |
+--------------------------+----------------------------+
| character_set_client | utf8  |
| character_set_connection | utf8  |
| character_set_database | utf8  |
| character_set_filesystem | binary  |
| character_set_results | utf8  |
| character_set_server | utf8  |
| character_set_system | utf8  |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

       可以看到所有的编码格式都会变成utf8,至此在建立数据库和数据表,数据字段的时候如果不特别指定,那么则会采用默认的编码方式,即现在的utf8。

       2,虽然编码格式从latin1变成了utf8,但是我这里还是遇到如下的问题。

Specified key was too long; max key length is 1000 bytes

       意思是key值长度大于1000个字节了,这里面的key值长度指的是定义key值时候的长度和乘以编码格式字节数,而不指实际长度。同时由于取1utf8=3字节(这个我是看别人都是这么说的,具体取多少我这边不确定),因此将其和乘以3之后就大于1000个字节了。原先latin1是没问题的(取的是1)。 

       解决办法即就是(1),缩减key值的定义长度。(2),不使用utf8编码。(3),因为默认DB engine 是MyIsAm,把其换成innodb。我使用方式(3),然后错误得以消除。

       3,这个时候又出现了如下问题:

ERROR: ER_TOO_LONG_KEY: Specified key was too long; max key length is 767 bytes

       这个问题的原因还是utf8所导致的,在latin1编码格式下,我设置了VARCHAR (512)类型为主键是没有问题的,而utf8则不行,是由于utf8编码取的是3字节,也就说,只能容纳256个utf8编码格式的VARCHAR。因此定义的时候定义为VARCHAR (255)问题得以消除,或者换一种数据类型。 

       4,至此我使用nodejs进行数据库的读写都是没有问题的,但是我在使用C 语言的时候,发现插入utf8编码的中文,仍然显示的是乱码。原因可能由多种,这里面我说一下我遇到的两种情况。首先确认本地系统的默认编码方式,使用locale命令进行查看(Linux),通常情况应该是utf8,为了保险期间,我在C语言中加入了如下的代码显示指定编码方式

#include <locale.h>
setlocale(LC_ALL, "en_US.UTF-8");

       这个时候,C语言执行mysql_query插入数据的时候,数据库仍然显示乱码。解决方法如下:

mysql_query(g_pMyConn, "set character set utf8");
mysql_query(g_pMyConn, g_strSqlStatement)

       即在执行数据库插入命令前,多加上一行显示的说明使用utf8方式执行。

       由于nodejs插入的时候没有C语言的问题,我就简单构想了一下如下原因,纯属个人猜测:

       由于C语言使用的是mysql官方提供的api接口,而且mysql是由于欧洲人开发的,开始的时候没想到会应用那么广泛,因此使用了latin1默认编码,随着mysql应用的人越来越多,因此在支持其他编码的时候就需要在原来的接口上打补丁,因此就会出现上面显示的指定编码格式,并没有做到接口和数据库默认编码能够自动保持一致的情况。 

       对于nodejs来说,连接数据库的行为会由nodejs进行封装,考虑的就相对全面,因此没有C 语言中的问题。

       最后我发现DB engine 从MyIsAm换成innodb,读取速度好变慢了,不知是啥原因,知道的麻烦告知一声。

以上所述是小编给大家介绍的nodejs和C语言插入mysql数据库乱码问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

NodeJs 相关文章推荐
Nodejs进程管理模块forever详解
Jun 01 NodeJs
NodeJS学习笔记之FS文件模块
Jan 13 NodeJs
浅谈Nodejs中的作用域问题
Dec 26 NodeJs
NodeJS遍历文件生产文件列表功能示例
Jan 22 NodeJs
windows 下安装nodejs 环境变量设置
Feb 02 NodeJs
nodejs入门教程二:创建一个简单应用示例
Apr 24 NodeJs
使用Nodejs连接mongodb数据库的实现代码
Aug 21 NodeJs
NodeJs之word文件生成与解析的实现代码
Apr 01 NodeJs
Nodejs异步流程框架async的方法
Jun 07 NodeJs
nodejs 递归拷贝、读取目录下所有文件和目录
Jul 18 NodeJs
Nodejs监控事件循环异常示例详解
Sep 22 NodeJs
NodeJS http模块用法示例【创建web服务器/客户端】
Nov 05 NodeJs
解析NodeJS异步I/O的实现
Apr 13 #NodeJs
详解nodejs微信公众号开发——6.自定义菜单
Apr 13 #NodeJs
nodejs个人博客开发第七步 后台登陆
Apr 12 #NodeJs
nodejs个人博客开发第六步 数据分页
Apr 12 #NodeJs
nodejs个人博客开发第五步 分配数据
Apr 12 #NodeJs
nodejs个人博客开发第四步 数据模型
Apr 12 #NodeJs
nodejs个人博客开发第三步 载入页面
Apr 12 #NodeJs
You might like
JavaScript实现拼音排序的方法
2012/11/20 Javascript
jquery监听div内容的变化具体实现思路
2013/11/04 Javascript
莱鸟介绍javascript onclick事件
2016/01/06 Javascript
一个用jquery写的判断div滚动条到底部的方法【推荐】
2016/04/29 Javascript
简单封装js的dom查询实例代码
2016/07/08 Javascript
jQuery对checkbox 复选框的全选全不选反选的操作
2016/08/09 Javascript
JS实现获取当前URL和来源URL的方法
2016/08/24 Javascript
使用jsonp实现跨域获取数据实例讲解
2016/12/25 Javascript
jQuery实现鼠标经过显示动画边框特效
2017/03/24 jQuery
JavaScript 字符串数字左补位,右补位,取固定长度,截位扩展函数代码
2017/03/25 Javascript
JS中利用FileReader实现上传图片前本地预览功能
2018/03/02 Javascript
vue2使用keep-alive缓存多层列表页的方法
2018/09/21 Javascript
layui--js控制switch的切换方法
2019/09/03 Javascript
解决在layer.open中使用时间控件laydate失败的问题
2019/09/11 Javascript
Jquery cookie插件实现原理代码解析
2020/08/04 jQuery
Antd中单个DatePicker限定时间输入范围操作
2020/10/29 Javascript
vuecli项目构建SSR服务端渲染的实现
2020/10/30 Javascript
举例详解Python中循环语句的嵌套使用
2015/05/14 Python
深入理解Python中range和xrange的区别
2017/11/26 Python
Python 给屏幕打印信息加上颜色的实现方法
2019/04/24 Python
python 字典访问的三种方法小结
2019/12/05 Python
Python 实现一个计时器
2020/07/28 Python
django和flask哪个值得研究学习
2020/07/31 Python
Django前后端分离csrf token获取方式
2020/12/25 Python
CSS3提交意见输入框样式代码
2014/10/30 HTML / CSS
详解HTML5中的picture元素响应式处理图片
2018/01/03 HTML / CSS
您的健身减肥和健康饮食专家:vitafy
2017/06/06 全球购物
会计学个人自荐信模板
2013/12/13 职场文书
中学门卫岗位职责
2013/12/26 职场文书
2014五一国际劳动节活动总结范文
2014/04/14 职场文书
教师竞聘演讲稿
2014/05/16 职场文书
建筑工地文明标语
2014/10/09 职场文书
2016教师六五普法学习心得体会
2016/01/21 职场文书
golang实现一个简单的websocket聊天室功能
2021/10/05 Golang
解决Mysql报错 Table 'mysql.user' doesn't exist
2022/05/06 MySQL
MySQL性能指标TPS+QPS+IOPS压测
2022/08/05 MySQL