《MySQL 权限与访问进阶:普通用户搭建、跨端登录及 C/C++ 开发对接教程》

**前引:**在 MySQL 开发与运维中,普通用户的创建与权限管控是保障数据库安全的基础,而本地连接、远程访问的配置,以及 C/C++ 程序的对接调用,则是打通 "数据库 - 应用" 链路的核心环节。很多开发者在实际操作中会遇到 "用户创建后登录失败""远程连接被拒绝""C/C++ 接口调用报错" 等问题,本文将从实战出发,一步步拆解 MySQL 普通用户的创建配置、本地 / 远程登录的关键步骤,以及 C/C++ 访问 MySQL 的完整流程(含环境搭建、代码实现、常见问题排查),帮助开发者快速搞定多场景下的 MySQL 访问需求!

目录

【一】普通用户的创建

(1)查看user表

(2)创建普通用户

(3)删除普通用户

(4)修改密码

(5)数据库权限

(6)回收权限

【二】使用C语言链接访问库

(1)下载库文件

(2)查看库文件

(3)语言检验

【三】语言操作库(接口学习)

(1)初始化

(2)设置字符集

(3)连接MySQL

(4)关闭连接

(5)操作指令

(1)增删

(2)获取输出内容

(6)完整代码


【一】普通用户的创建

(1)查看user表

user表属于mysql数据库,需先切换到该库:

cpp 复制代码
use mysql;  -- 切换到mysql数据库

再在 user 表查看账户:

cpp 复制代码
select host,user,authentication_string from user;
(2)创建普通用户

注意:本地登录,'登录主机/ip'填 localhost 即可,想简单的公网登录填 %

cpp 复制代码
create user '用户名'@'登陆主机/ip' identified by '密码'; 
(3)删除普通用户

主机名可以用上面的 localhost 或者 % 替换,也可以用真实的主机IP

cpp 复制代码
drop user '用户名'@'主机名';
(4)修改密码

自己改自己的密码:

cpp 复制代码
drop user '用户名'@'主机名';

root 账号改指定普通用户的密码:

cpp 复制代码
set password for '用户名'@'主机名'=password('新的密码');
(5)数据库权限

权限列表如下,基本就是任务指令关键字:

给用户添加权限:

cpp 复制代码
grant 权限列表 on 库.对象名 to '用户名'@'登陆位置';

* . * : 代表本系统中的所有数据库的所有对象(表,视图,存储过程等)

库 . * : 表示某个数据库中的所有数据对象(表,视图,存储过程等)

例如:

刷新权限:

cpp 复制代码
flush privileges;

然后使用 newuser 普通用户登入访问授权的数据库和表:

(6)回收权限
cpp 复制代码
revoke 权限列表 on 库.对象名 from '用户名'@'登陆位置';

【二】使用C语言链接访问库

如果是C++语言,原理相同!

(1)下载库文件

如果你想要挑战自己,可以去官网下载,再导入:

https://dev.mysql.com/downloads/

如果你是 Ubuntu ,可以终端直接执行下面指令安装库:

cpp 复制代码
sudo apt update && sudo apt install libmysqlclient-dev
(2)查看库文件
cpp 复制代码
# 列出包对应的所有文件(包括头文件、库文件)
dpkg -L libmysqlclient-dev

库文件被放在 /usr/include/mysql 目录下:可以看到有 mysql.h

(3)语言检验

利用下面的函数来检验库文件是否导入成功:

cpp 复制代码
mysql_get_client_info()

注意:编译需要告诉编译器头文件和库文件的位置,先找头文件再链接库文件

复制代码
//                   告诉头文件位置         告诉库位置                  告诉哪个库
gcc -o Hello ceshi.c -I/usr/include/mysql -L/usr/lib/x86_64-linux-gnu -lmysqlclient

【三】语言操作库(接口学习)

(1)初始化
cpp 复制代码
mysql_init(null);

例如:

(2)设置字符集
cpp 复制代码
mysql_options(初始化的mysql指针, MYSQL_SET_CHARSET_NAME, "utf8mb4");

例如:

(3)连接MySQL
cpp 复制代码
mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag);
参数 含义 场景取值
mysql 已初始化的MYSQL句柄指针 mysql_init()返回的指针
host MySQL 服务器地址 本地连接填"localhost""127.0.0.1"或具体IP
user MySQL 登录用户名 你的"newuser"
passwd 登录密码 newuser的实际密码(如"123456"
db 要默认连接的数据库名 你需要访问的数据库(如"testdb",填NULL则不指定)
port MySQL 服务端口 默认3306
unix_socket 本地套接字文件(仅 Unix/Linux) 本地连接填NULL(使用默认套接字)
client_flag 连接标志(如压缩、SSL 等) 默认填0即可

例如:

(4)关闭连接
cpp 复制代码
//关闭连接,释放资源
mysql_close(mysql_init返回的指针);
(5)操作指令
(1)增删
cpp 复制代码
int mysql_query(MYSQL *mysql, const char *stmt_str);
  • 参数:mysql为连接句柄,stmt_str为要执行的 SQL 字符串
  • 返回值:成功返回0,失败返回非0

例如:现在有一个表,我用语言执行插入

重新编译+执行:

结果:

(2)获取输出内容

解决问题:如果利用mysql__query执行打印相关的语句,比如select是无法显示的

其实它是将输出的内容信息放在一个二维矩阵里面,二级指针的形式,返回给我们行和列,只要遍历它返回的行和列也就遍历了整个二维字符串数组,拿到了输出内容,下面是接口:

cpp 复制代码
//获取结果集,有了这个函数才可以继续
MYSQL_RES *result = mysql_store_result(mysql_init的返回值);
cpp 复制代码
//关闭文件接口
mysql_free_result(result);

**注意:**上面这个result相当于就是文件接口,使用完需要及时关闭

cpp 复制代码
//获取结果行数
my_ulonglong mysql_num_rows(MYSQL_RES *res);
  • 参数resmysql_store_result()返回的结果集指针
  • 返回值 :结果集的行数(my_ulonglong是无符号长整型,可通过%llu格式化输出)
cpp 复制代码
//获取结果列数
unsigned int mysql_num_fields(MYSQL_RES *res);
  • 参数res是结果集指针
  • 返回值:结果集的列数(无符号整数)
cpp 复制代码
//获取列名称
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);
  • 参数res是结果集指针。
  • 返回值MYSQL_FIELD结构体数组,数组长度等于mysql_num_fields(res)的返回值。每个MYSQL_FIELD结构体的核心成员包括:
    • name:列名(字符串);
    • type:列的数据类型(如MYSQL_TYPE_INT对应 INT 类型);
    • length:列的定义长度。

例如:

(6)完整代码
cpp 复制代码
#include<stdio.h>
#include<mysql.h>

int main()
{
    //初始化
    MYSQL* my =mysql_init(NULL);
    if(my==NULL)
    {
        printf("sorry,mysql_init is errno");
    }

    //设置字符集
    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");
    //打印数据(row用来读取每一行的数据)
    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;
}
相关推荐
那我掉的头发算什么2 小时前
【图书管理系统】基于Spring全家桶的图书管理系统(下)
java·数据库·spring boot·后端·spring·mybatis
t***442313 小时前
MySQL 导出数据
数据库·mysql·adb
翔云12345613 小时前
MySQL主从库复制中,主库如何查找对应日志文件位置
数据库·mysql
Mr_star_galaxy14 小时前
【MySQL基础】视图和权限管理
数据库·mysql
lipiaoshuigood16 小时前
MySQL 数据出海之数据同步方案
数据库·mysql
笨蛋不要掉眼泪16 小时前
Nacos配置中心详解:核心用法、动态刷新与经典面试题解析
java·数据库·后端
@@神农16 小时前
PostgreSQL-SQL语句的执行过程(一)
数据库·sql·postgresql
Andy Dennis17 小时前
一文漫谈数据库存储之索引(B+, B-link, LSM tree等)
数据库·b+树·lsm-tree
CHANG_THE_WORLD18 小时前
字符串定义的汇编分析
汇编·数据库