溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

nodejs和C語(yǔ)言插入mysql數(shù)據(jù)庫(kù)亂碼怎么辦

發(fā)布時(shí)間:2021-07-13 15:35:03 來(lái)源:億速云 閱讀:137 作者:小新 欄目:web開(kāi)發(fā)

這篇文章將為大家詳細(xì)講解有關(guān)nodejs和C語(yǔ)言插入mysql數(shù)據(jù)庫(kù)亂碼怎么辦,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

在這里記錄了nodejs過(guò)程中的一些亂碼情況,這里的亂碼主要是由于網(wǎng)頁(yè)的編碼方式與nodejs的默認(rèn)解碼方式(utf8)不一致所造成的。這一次要說(shuō)一下的是在C語(yǔ)言和nodejs與MySQL進(jìn)行交互的時(shí)候出現(xiàn)的亂碼問(wèn)題。

       1,由于爬蟲(chóng)程序在多個(gè)Docker中執(zhí)行,因此我需要定期的同步每一個(gè)docker中的mysql數(shù)據(jù)到一個(gè)全局的mysql數(shù)據(jù)表中。使用nodejs進(jìn)行數(shù)據(jù)同步,出現(xiàn)中文亂碼。要知道在每一docker中的中文是不存在亂碼的。原因是nodejs默認(rèn)處理字符是utf8,而mysql默認(rèn)是latin1,畢竟是歐洲人開(kāi)發(fā)的數(shù)據(jù)庫(kù)。分析如下

       命令show variables like 'char%';得到的結(jié)果如下:

+--------------------------+----------------------------+
| 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/ |
+--------------------------+----------------------------+

       即在建立數(shù)據(jù)庫(kù)的時(shí)候不特別指定,則數(shù)據(jù)庫(kù),數(shù)據(jù)表的以及數(shù)據(jù)字段的編碼格式為默認(rèn)值,而默認(rèn)值在不更改配置文件的時(shí)候是latin1(默認(rèn)安裝形式)。由于utf8是較為通用的編碼方式,因此我們將數(shù)據(jù)庫(kù)的所有編碼方式改為utf8。這里需要說(shuō)明的是mysql的編碼分為好幾個(gè)層次,包括數(shù)據(jù)庫(kù)級(jí)別,數(shù)據(jù)表級(jí)別以及數(shù)據(jù)字段級(jí)別等,我這里沒(méi)有去深究這些方面,一個(gè)個(gè)去設(shè)置每個(gè)字段,每個(gè)表的編碼方式,而是把所有的編碼方式均設(shè)置為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服務(wù)service mysqld restart

       命令show variables like 'char%';再次查看編碼格式,得到的結(jié)果如下:

+--------------------------+----------------------------+
| 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/ |
+--------------------------+----------------------------+

       可以看到所有的編碼格式都會(huì)變成utf8,至此在建立數(shù)據(jù)庫(kù)和數(shù)據(jù)表,數(shù)據(jù)字段的時(shí)候如果不特別指定,那么則會(huì)采用默認(rèn)的編碼方式,即現(xiàn)在的utf8。

       2,雖然編碼格式從latin1變成了utf8,但是我這里還是遇到如下的問(wèn)題。

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

       意思是key值長(zhǎng)度大于1000個(gè)字節(jié)了,這里面的key值長(zhǎng)度指的是定義key值時(shí)候的長(zhǎng)度和乘以編碼格式字節(jié)數(shù),而不指實(shí)際長(zhǎng)度。同時(shí)由于取1utf8=3字節(jié)(這個(gè)我是看別人都是這么說(shuō)的,具體取多少我這邊不確定),因此將其和乘以3之后就大于1000個(gè)字節(jié)了。原先latin1是沒(méi)問(wèn)題的(取的是1)。 

       解決辦法即就是(1),縮減key值的定義長(zhǎng)度。(2),不使用utf8編碼。(3),因?yàn)槟J(rèn)DB engine 是MyIsAm,把其換成innodb。我使用方式(3),然后錯(cuò)誤得以消除。

       3,這個(gè)時(shí)候又出現(xiàn)了如下問(wèn)題:

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

       這個(gè)問(wèn)題的原因還是utf8所導(dǎo)致的,在latin1編碼格式下,我設(shè)置了VARCHAR (512)類型為主鍵是沒(méi)有問(wèn)題的,而utf8則不行,是由于utf8編碼取的是3字節(jié),也就說(shuō),只能容納256個(gè)utf8編碼格式的VARCHAR。因此定義的時(shí)候定義為VARCHAR (255)問(wèn)題得以消除,或者換一種數(shù)據(jù)類型。 

       4,至此我使用nodejs進(jìn)行數(shù)據(jù)庫(kù)的讀寫(xiě)都是沒(méi)有問(wèn)題的,但是我在使用C 語(yǔ)言的時(shí)候,發(fā)現(xiàn)插入utf8編碼的中文,仍然顯示的是亂碼。原因可能由多種,這里面我說(shuō)一下我遇到的兩種情況。首先確認(rèn)本地系統(tǒng)的默認(rèn)編碼方式,使用locale命令進(jìn)行查看(Linux),通常情況應(yīng)該是utf8,為了保險(xiǎn)期間,我在C語(yǔ)言中加入了如下的代碼顯示指定編碼方式

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

       這個(gè)時(shí)候,C語(yǔ)言執(zhí)行mysql_query插入數(shù)據(jù)的時(shí)候,數(shù)據(jù)庫(kù)仍然顯示亂碼。解決方法如下:

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

       即在執(zhí)行數(shù)據(jù)庫(kù)插入命令前,多加上一行顯示的說(shuō)明使用utf8方式執(zhí)行。

       由于nodejs插入的時(shí)候沒(méi)有C語(yǔ)言的問(wèn)題,我就簡(jiǎn)單構(gòu)想了一下如下原因,純屬個(gè)人猜測(cè):

       由于C語(yǔ)言使用的是mysql官方提供的api接口,而且mysql是由于歐洲人開(kāi)發(fā)的,開(kāi)始的時(shí)候沒(méi)想到會(huì)應(yīng)用那么廣泛,因此使用了latin1默認(rèn)編碼,隨著mysql應(yīng)用的人越來(lái)越多,因此在支持其他編碼的時(shí)候就需要在原來(lái)的接口上打補(bǔ)丁,因此就會(huì)出現(xiàn)上面顯示的指定編碼格式,并沒(méi)有做到接口和數(shù)據(jù)庫(kù)默認(rèn)編碼能夠自動(dòng)保持一致的情況。 

       對(duì)于nodejs來(lái)說(shuō),連接數(shù)據(jù)庫(kù)的行為會(huì)由nodejs進(jìn)行封裝,考慮的就相對(duì)全面,因此沒(méi)有C 語(yǔ)言中的問(wèn)題。

       最后我發(fā)現(xiàn)DB engine 從MyIsAm換成innodb,讀取速度好變慢了,不知是啥原因,知道的麻煩告知一聲。

關(guān)于“nodejs和C語(yǔ)言插入mysql數(shù)據(jù)庫(kù)亂碼怎么辦”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI