在 MySQL 开发与运维中,普通用户的创建与权限管控是保障数据库安全的基础,而本地连接、远程访问的配置,以及 C/C++ 程序的对接调用,则是打通'数据库 - 应用'链路的核心环节。很多开发者在实际操作中会遇到'用户创建后登录失败''远程连接被拒绝''C/C++ 接口调用报错'等问题,本文从实战出发,拆解 MySQL 普通用户的创建配置、本地/远程登录的关键步骤,以及 C/C++ 访问 MySQL 的完整流程。
普通用户的创建与管理
查看 user 表
user表属于 mysql数据库,需先切换到该库:
use mysql;
再在 user 表查看账户信息:
select host,user,authentication_string from user;

创建普通用户
注意:本地登录时,主机名填 localhost;若需公网登录,可填 %。
create user '用户名'@'登陆主机/ip' identified by '密码';
删除普通用户
主机名可用 localhost、% 或真实 IP 替换:
drop user '用户名'@'主机名';
修改密码
修改当前用户密码:
set password for '用户名'@'主机名'=password('新的密码');
数据库权限
权限列表基本对应 SQL 指令关键字。给用户添加权限:
grant 权限列表 on 库。对象名 to '用户名'@'登陆位置';
其中 *.* 代表所有数据库的所有对象,库.* 表示某个数据库中的所有数据对象。
刷新权限使配置生效:
flush privileges;
随后使用新创建的普通用户登入授权后的数据库和表进行验证。
回收权限
如需收回权限,执行以下语句:
revoke 权限列表 on 库。对象名 from '用户名'@'登陆位置';
使用 C 语言链接访问库
如果是 C++ 语言,原理相同。
下载库文件
推荐直接通过包管理器安装,以 Ubuntu 为例:
sudo apt update && sudo apt install libmysqlclient-dev
查看库文件
安装完成后,头文件和库文件通常位于 /usr/include/mysql 目录下,可以看到 mysql.h。

编译时需要指定头文件和库文件的位置。
语言检验
利用 mysql_get_client_info() 函数可以检验库文件是否导入成功。
语言操作库(接口学习)
初始化
首先初始化 MYSQL 结构体:
MYSQL *my = mysql_init(NULL);
设置字符集
建议显式设置字符集以避免乱码:
mysql_options(my, MYSQL_SET_CHARSET_NAME, "utf8mb4");
连接 MySQL
使用 mysql_real_connect 建立连接,参数说明如下:
| 参数 | 含义 | 场景取值 |
|---|---|---|
mysql | 已初始化的句柄指针 | mysql_init()返回的指针 |
host | MySQL 服务器地址 | 本地填"localhost"或"127.0.0.1" |
user | MySQL 登录用户名 | 你的用户名 |
passwd | 登录密码 | 实际密码 |
db | 默认连接的数据库名 | 如"testdb",不指定填NULL |
port | MySQL 服务端口 | 默认3306 |
unix_socket | 本地套接字文件 | 本地连接填NULL |
client_flag | 连接标志 | 默认填0 |

关闭连接
使用完毕后及时释放资源:
mysql_close(my);
操作指令
增删改查
执行 SQL 语句使用 mysql_query,成功返回 0,失败返回非 0:
int mysql_query(MYSQL *mysql, const char *stmt_str);
例如插入数据后重新编译执行,观察结果变化。




获取输出内容
mysql_query无法直接显示查询结果,需将输出内容放入二维矩阵中遍历。核心接口如下:
//获取结果集
MYSQL_RES *result = mysql_store_result(my);
//关闭结果集
mysql_free_result(result);
//获取行数
my_ulonglong mysql_num_rows(MYSQL_RES *res);
//获取列数
unsigned int mysql_num_fields(MYSQL_RES *res);
//获取列名称
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);
注意:result 相当于文件句柄,使用完需及时关闭。
完整代码示例
#include<stdio.h>
#include<mysql.h>
int main() {
// 初始化
MYSQL* my = mysql_init(NULL);
if(my == NULL) {
printf("sorry, mysql_init is errno");
return 1;
}
// 设置字符集
mysql_options(my, MYSQL_SET_CHARSET_NAME, "utf8mb4");
// 连接 MySQL
mysql_real_connect(my, "localhost", "newuser", "123456", "hello", (unsigned int)3306, NULL, (unsigned long)0);
// 执行查询
const char* ptr = "select * from student";
mysql_query(my, ptr);
// 获取结果集
MYSQL_RES *result = mysql_store_result(my);
// 获取行数和列数
my_ulonglong row_count = mysql_num_rows(result);
unsigned int col_count = mysql_num_fields(result);
// 获取列名称
MYSQL_FIELD *fields = mysql_fetch_fields(result);
// 打印列名称
for(unsigned int i=0; i<col_count; i++) {
printf("%s\t", fields[i].name);
}
printf("\n");
// 打印数据
MYSQL_ROW row;
while (row = mysql_fetch_row(result)) {
for (unsigned int i = 0; i < col_count; i++) {
printf("%s\t", row[i]);
}
printf("\n");
}
// 释放资源
mysql_free_result(result);
mysql_close(my);
return 0;
}

