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服务器(9):实现非阻塞操作
Dec 18 NodeJs
使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室
Aug 21 NodeJs
nodejs的压缩文件模块archiver用法示例
Jan 18 NodeJs
基于Nodejs利用socket.io实现多人聊天室
Feb 22 NodeJs
NodeJS学习笔记之Module的简介
Mar 24 NodeJs
详解nodejs微信公众号开发——2.自动回复
Apr 10 NodeJs
NodeJs的fs读写删除移动监听
Apr 28 NodeJs
nodejs express配置自签名https服务器的方法
May 22 NodeJs
手把手教你如何使用nodejs编写cli命令行
Nov 05 NodeJs
nodejs通过钉钉群机器人推送消息的实现代码
May 05 NodeJs
在NodeJs中使用node-schedule增加定时器任务的方法
Jun 08 NodeJs
分享node.js实现简单登录注册的具体代码
Apr 26 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
星际争霸中的热键
2020/03/04 星际争霸
php将远程图片保存到本地服务器的实现代码
2015/08/03 PHP
PHP全局使用Laravel辅助函数dd
2019/12/26 PHP
通用javascript脚本函数库 方便开发
2009/10/13 Javascript
Javascript 网页水印(非图片水印)实现代码
2010/03/01 Javascript
javascript 窗口加载蒙板 内嵌网页内容
2010/11/19 Javascript
jquery监控数据是否变化(修正版)
2011/04/12 Javascript
jQuery 阴影插件代码分享
2012/01/09 Javascript
一个页面放2段图片滚动代码出现冲突的问题如何解决
2012/12/21 Javascript
使用npm发布Node.JS程序包教程
2015/03/02 Javascript
jquery实现的简单二级菜单效果代码
2015/09/22 Javascript
Bootstrap树形组件jqTree的简单封装
2016/01/25 Javascript
AngularJS 面试题集锦
2016/09/06 Javascript
jQuery动态产生select option下拉列表
2017/03/15 Javascript
jquery实现异步加载图片(懒加载图片一种方式)
2017/04/24 jQuery
MvcPager分页控件 适用于Bootstrap
2017/06/03 Javascript
用原生JS实现简单的多选框功能
2017/06/12 Javascript
elementUI中Table表格问题的解决方法
2018/12/04 Javascript
使用react render props实现倒计时的示例代码
2018/12/06 Javascript
微信小程序 腾讯地图显示偏差问题解决
2019/07/27 Javascript
[03:49]DOTA2 2015国际邀请赛中国区预选赛第二日现场百态
2015/05/27 DOTA
python回调函数用法实例分析
2015/05/09 Python
Python中使用遍历在列表中添加字典遇到的坑
2019/02/27 Python
Python 实现网课实时监控自动签到、打卡功能
2020/03/12 Python
Python3+selenium实现cookie免密登录的示例代码
2020/03/18 Python
Python爬虫爬取百度搜索内容代码实例
2020/06/05 Python
Python 如何展开嵌套的序列
2020/08/01 Python
Python包资源下载路径报404解决方案
2020/11/05 Python
大学毕业生通用求职信
2013/09/28 职场文书
应届生法律顾问求职信
2013/11/19 职场文书
假面舞会策划方案
2014/05/29 职场文书
垃圾桶标语
2014/06/24 职场文书
入党积极分子学习优秀共产党员先进事迹思想汇报
2014/09/13 职场文书
2014年安全工作总结范文
2014/11/13 职场文书
2014年财政局工作总结
2014/12/09 职场文书
材料员岗位职责范本
2015/04/11 职场文书