曾嘗試用Qt自帶的接口對數據庫進行訪問,發現效率不如原本自帶的接口高,所以就採用了MySQL提供的C語言接口。
寫SQL語句難度並不大,應該是我的數據庫存儲需求也複雜吧。對比較重要的幾點做一下記錄,以便後續需要的時候進行深入。
(1)數據庫的類型
數據庫引擎有默認是InnoDB,這種格式如果要將其導入到其他主機的或者移植是通道SQL語句導入導出的方式,而MyISAM則可以直接將文件拷貝到新主機或者新的“database root”後,就可以加載訪問,移植比較簡單。
https://www.jianshu.com/p/4bb9f78b4f6d
(2)數據庫連接和表的創建。
在我使用MYSQL的C接口連接數據庫的時候,可以先連接服務器後選擇數據庫,也就是數據庫名稱傳入NULL。
也可以先連接上默認有的數據庫“test”,再進行數據庫的創建,後再選擇創建的數據庫。
創建數據庫後,仍然遇到一些問題,新建的存儲圖像的表出現訪問問題,查詢該數據庫的大小並不能得到結果,返回值爲NULL,
std::string sql;
sql = "CREATE Database if not exists 數據庫名 DEFAULT CHARACTER SET utf8;";
int r;
r = mysql_send_query(con, sql.data(), sql.length());
sql = "GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER ON 數據庫名.*TO 數據庫名@localhost IDENTIFIED BY '123456';";
r = mysql_send_query(con, sql.data(), sql.length());
查詢數據庫大小代碼:
MYSQL_RES *result = NULL;
MYSQL_ROW sql_row;
string sql;
sql = "select concat(round(sum(data_length/1024/1024),2)) as data_length_MB from information_schema.tables "
"where table_schema ='數據庫名' and table_name = '";
string sqlend = "';";
string basename = "errpic";
string num = std::to_string(i);
string errpicname = basename + num;
string finalsql = sql + errpicname + sqlend;
mysql_query(_con, finalsql.data());
result = mysql_store_result(_con);
if (result != NULL)
{
sql_row = mysql_fetch_row(result);
if (*sql_row != NULL)
{
/////
}
}
上面的代碼測試過沒有問題,但是在新建了數據庫後,查詢大小後result指針一直是NULL,最後只好通過重新連接數據庫來解決,在第一次創建並選擇對應數據庫後進行大小訪問並不成功。。。(原因還不明確)
數據庫重新連接代碼:
mysql_close(con);
con = mysql_init(NULL);
Connect = mysql_real_connect(con, host.data(), user.data(), pswd.data(), table_schema.data(), port, NULL, 0);
if (Connect == NULL)
{
connectflag = 0;
return;
}
(3)圖像數據的存儲
圖像數據的存儲比較方便的方式是採用SQL語句注入,數據採用MYSQL_TYPE_MEDIUM_BLOB類型,
不同類型的BLob數據的大小:
MySQL的四種BLOB類型
類型 大小(單位:字節)
TinyBlob 最大 255
Blob 最大 65K
MediumBlob 最大 16M
LongBlob 最大 4G
該方式插入數據需要更改my.ini文件
# The maximum size of one packet or any generated or intermediate string, or any parameter sent by the
# mysql_stmt_send_long_data() C API function.
max_allowed_packet=30M
原始的大小是4M,改爲適合大小即可。具體代碼摘自這位博主: