R語言通過RMySQL包操作mysql數據庫(on linux) - 如何避免讀寫中文時亂碼

環境是CentOS7,Rstudio

 

1.Rmysql庫安裝
注意: Rmysql庫依賴DBI庫

install.packages("DBI")
install.packages("RMySQL") 或 install.packages('RMySQL',type='source')

查看已安裝的包:
.packages(all.available=TRUE)

至此安裝完畢,如果中間過程還出問題,可能底層C++環境欠缺
參考:https://www.jianshu.com/p/d57355c57876


2.
另外R連接mysql會出現中文亂碼變問號情況,查到COS上一個貼子,解決方案如下:
在MySQL的配置文件/etc/mysql/my.cnf中[client]標籤下加default-character-set=utf8 

這個我試了,總是報錯。我用的docker版的mysql,是這個原因嗎?
後面避免讀寫中文亂碼,使用的是sql語句。

library(DBI)
library(RMySQL)
con<-dbConnect(MySQL(),user='root', password='123456',dbname='wang',host='y.biomooc.com',
               port=7070, DBMsencoding='utf8')
dbSendQuery(con,'SET NAMES utf8;') #讀取防中文亂碼
query<-dbSendQuery(con,'alter database wang character set utf8;') #寫入防中文亂碼
#
query<-dbSendQuery(con,'select * from fruits;')
data=fetch(query);
data #獲得數據框

3. 在R中使用RMySQL
library(DBI)
library(RMySQL)
#help(package="RMySQL") #查看說明文檔

##連接數據庫
con<-dbConnect(MySQL(),user='root', password='123456',dbname='wang',host='y.biomooc.com',port=7070, DBMsencoding='utf8')
## 連接linux本地的mysql不需要輸入host,默認port=3306。

##關閉數據庫
## dbDisconnect(con) 


(1)查詢:dbSendQuery的使用 
dbSendQuery返回的MySQLResult類型,而dbGetQuery直接返回數據框data.frame

dbSendQuery(con,'SET NAMES utf8') #先執行這一句,防止中文顯示亂碼


#i) 用sql語句查詢,獲得數據框
res<-dbSendQuery(con,'select * from cell_c1 limit 3;')
data<-fetch(res, n=3) #返回數據框前5行,默認n=-1返回所有數據
data

dbClearResult(res) #清除數據


#ii) 用R函數,讀整個數據表  
tb=dbReadTable(con,"result")
tb
##   name subject score
## 1 張三    數學    90
## 2 張三    語文    50
## 3 張三    地理    40
## 4 李四    語文    55
## 5 李四    政治    45
## 6 王五    政治    30

(2)查看狀態
> summary(con) #獲取連接信息
<MySQLConnection:0,0>
  User:   root 
  Host:   y.biomooc.com 
  Dbname: wang 
  Connection type: y.biomooc.com via TCP/IP 

Results:
<MySQLResult:0,0,0>
  Statement: select * from cell_c1 limit 3; 
  Has completed? yes 
  Affected rows: -1 
  Rows fetched: 3 
NULL


dbGetInfo(con) #獲取連接信息
dbListTables(con) #查看database下所有表格


ii) 防止中文亂碼
mysql> show variables like "char%";
+------------ -------------+------------ ---------------+
| Variable_name            | Value                      |
+----------- --------------+------------- --------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | latin1                     | #改爲utf8寫入才能避免R寫入中文時亂碼
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+----------- --------------+---------- -----------------+
8 rows in set (0.01 sec)

#防止寫入中文時亂碼
dbSendQuery(con,'alter database wang character set utf8;') #數據庫改爲utf8,否則寫入會中文亂碼

#查詢字符集
query<-dbSendQuery(con,'show variables like "char%";')
df=fetch(query) #返回值是數據框


(3)寫數據庫表: 創建新表,寫入 
#dbWriteTable(conn, "tablename", data) #寫表

#寫表,把fruits寫入水果數據表"fruits"
fruits <-data.frame(id=1:5,name=c("蘋果","香蕉","梨子","玉米","西瓜"),price=c(8.8,4.98,7.8,6,2.1),status=c("無","打折","無","售罄","批發"))  
dbListTables(con)
dbWriteTable(con,"fruits",fruits,row.names=F, fileEncoding="utf-8")  #寫入中文亂碼!編碼一致就正常了
dbListTables(con)


#使用sql查詢
query<-dbSendQuery(con,'select * from fruits limit 3;')
data<-fetch(query)

#追加數據表,是否覆蓋
#new_info <- data.frame(user_id=6:7,user_name=c("小明","小紅"),score = c(82,74))
#dbWriteTable(conn,"student_info ",new_info, append=T,row.names=F) #追加數據
#dbWriteTable(conn," student_info ",testB,overwrite=T,row.names=F)#覆蓋數據

new_info <- data.frame(id=6:7,name=c("水果1","水果2"),price = c(8.2,7.4),status=c("打折","批發"))
dbWriteTable(con,"fruits",new_info,append=T,row.names=F) #追加數據
dbWriteTable(con,"fruits",new_info,overwrite=T,row.names=F)#覆蓋數據:以前的數據被清空,現在只有這個新增的數據了

(4)刪除表
dbRemoveTable(con, "fruits")

(5)其他方法
summary(con) #連接信息

dbGetInfo(con)

dbListTables(con) #列出所有的表

dbExistsTable(con,'table_name')#是否存在表

dbListResults(con) #列出所有的結果

dbClearResult(res) #清除結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章