相比 PHP/Java 等高級語言,C 語言直接調用 MySQL C API(libmysqlclient)具有:零解析開銷、內存佔用極低、可嵌入高性能服務、支持連接池精細控制。常用於高頻交易、游戲服務端、數據采集代理等場景。
代表一個到 MySQL Server 的連接會話,包含網絡層、協議版本、線程 ID、字符集、事務狀態等:
typedef struct st_mysql {
NET net; // 通信參數
char *host, *user, *passwd; // 連接信息
unsigned int port, client_flag, server_capabilities;
unsigned long thread_id; // 服務端線程ID
my_ulonglong affected_rows; // 影響行數
my_ulonglong insert_id; // 自增ID
MYSQL_FIELD *fields; // 結果集字段元數據
struct st_mysql_options options; // 選項
struct charset_info_st *charset; // 字符集
} MYSQL;
SELECT/SHOW/DESCRIBE/EXPLAIN 返回的結果集元數據與數據指針:
typedef struct st_mysql_res {
my_ulonglong row_count; // 行數
unsigned int field_count; // 列數
MYSQL_FIELD *fields; // 字段定義數組
MYSQL_DATA *data; // 數據緩衝區
MYSQL_ROWS *data_cursor; // 當前行游標
MYSQL_ROW row; // 當前行數據
unsigned long *lengths; // 每列長度
MYSQL handle; // 關聯連接句柄
my_bool eof; // 讀取結束標誌
} MYSQL_RES;
MYSQL_ROW:char **,單行數據,row[i] 為第 i 列字符串(NULL 表示 SQL NULL)MYSQL_FIELD:字段元數據(名、類型、長度、標誌、小數位等)| 函數 | 功能 | 關鍵參數 | 返回值 |
|---|---|---|---|
| mysql_init | 初始化 MYSQL 結構 | MYSQL* (可為 NULL) | 初始化後的 MYSQL* |
| mysql_real_connect | 建立真實連接 | host, user, passwd, db, port, unix_socket, client_flag | 連接句柄 / NULL |
| mysql_query | 執行 SQL 語句 | SQL 字符串 | 0 成功 / 非 0 失敗 |
| mysql_store_result | 獲取完整結果集(緩衝) | 連接句柄 | MYSQL_RES* / NULL |
| mysql_use_result | 獲取流式結果集(非緩衝) | 連接句柄 | MYSQL_RES* / NULL |
| mysql_fetch_row | 取下一行 | 結果集句柄 | MYSQL_ROW / NULL |
| mysql_num_fields | 獲取列數 | 結果集句柄 | unsigned int |
| mysql_affected_rows | 影響行數 | 連接句柄 | my_ulonglong (-1 錯誤) |
| mysql_insert_id | 最後自增 ID | 連接句柄 | my_ulonglong |
| mysql_free_result | 釋放結果集 | 結果集句柄 | void |
| mysql_close | 關閉連接並釋放 | 連接句柄 | void |
| mysql_error | 獲取錯誤信息 | 連接句柄 | const char* |
| mysql_errno | 獲取錯誤碼 | 連接句柄 | unsigned int |
#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>
#define QUERY_FMT "SELECT username FROM tbb_user WHERE userid = %d"
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "Usage: %s \n", argv[0]);
return 1;
}
MYSQL mysql, *sock;
MYSQL_RES *res;
MYSQL_ROW row;
char query[256];
mysql_init(&mysql);
if (!(sock = mysql_real_connect(&mysql, "localhost", "dbuser", "dbpass", "mydb", 0, NULL, 0))) {
fprintf(stderr, "Connect failed: %s\n", mysql_error(&mysql));
return 1;
}
snprintf(query, sizeof(query), QUERY_FMT, atoi(argv[1]));
if (mysql_query(sock, query)) {
fprintf(stderr, "Query failed: %s\n", mysql_error(sock));
mysql_close(sock);
return 1;
}
if (!(res = mysql_store_result(sock))) {
fprintf(stderr, "Store result failed: %s\n", mysql_error(sock));
mysql_close(sock);
return 1;
}
printf("Fields: %d\n", mysql_num_fields(res));
while ((row = mysql_fetch_row(res))) {
printf("User #%s: %s\n", argv[1], row[0] ? row[0] : "NULL");
}
mysql_free_result(res);
mysql_close(sock);
return 0;
}
gcc -o mysql_select mysql_select.c \
-I/usr/local/mysql/include \
-L/usr/local/mysql/lib \
-lmysqlclient -lz -lm -lpthread
-I:頭文件路徑(含 mysql.h)-L:庫文件路徑(含 libmysqlclient.so/a)-lmysqlclient:鏈接客戶端庫-lz -lm -lpthread:依賴庫(壓縮、數學、線程)./mysql_select 1
# Fields: 1
# User #1: admin
mysql_stmt_prepare/execute/bind_param/bind_result,防注入、提升重複執行性能mysql_real_connect_nonblocking + epoll/kqueue 實現高併發libmysqld,無獨立進程,適合單機應用C 語言操作 MySQL 核心流程:初始化 → 連接 → 執行 → 獲取結果集 → 逐行讀取 → 釋放資源 → 關閉連接。掌握三大結構體(MYSQL/MYSQL_RES/MYSQL_ROW)與十大核心 API,配合正確編譯鏈接參數,即可構建高性能、低延遲的數據庫訪問層。