MySQL用户与权限管理
为了数据库安全,避免始终使用root超级账户,MySQL提供了完整的用户与权限管理机制。
用户管理
1.用户信息存储
MySQL的所有用户信息都存储在系统数据库 mysql 的 user 表中。
-
host: 允许登录的主机(如localhost表示仅限本机) -
user: 用户名 -
authentication_string: 加密后的密码 -
*_priv: 各种权限的布尔值字段
2. 创建用户
语法:
CREATE USER '用户名'@'登陆主机/IP' IDENTIFIED BY '密码';
说明:
- 创建后用户暂无权限,需要额外授权
- 避免使用
'用户名'@'%'(允许从任何主机登录)以减少安全风险(%表示可以让用户在任意主机登录)
3. 删除用户
语法:
DROP USER '用户名'@'主机名';
注意: 必须同时指定用户名和主机名才能唯一确定并删除用户。
这里创建用户,本质上也就是在
mysql数据库里的user数据表中插入一条记录。删除用户,本质就是在
mysql数据库里的user数据表中删除一条记录
4. 修改用户密码
语法:
- 用户修改自己密码:
SET PASSWORD = PASSWORD('新密码'); - root修改其他用户密码:
SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');
这里修改密码时需要使用password函数进行加密。(在创建用户时设置密码,在user表中存储的也是加密后的密码)
权限管理
1. 授予权限
语法:
GRANT 权限列表 ON 数据库.对象名 TO '用户名'@'登陆位置';
说明:
-
权限列表:如
SELECT, INSERT, DELETE,或用ALL代表所有权限 -
授权范围:
-
*.*:所有数据库的所有对象 -
数据库名.*:指定数据库的所有对象 -
数据库名.表名:指定数据库的特定表
-
2. 回收权限
语法:
REVOKE 权限列表 ON 数据库.对象名 FROM '用户名'@'登陆位置';
注意: 权限变更后,有时需执行FLUSH PRIVILEGES;来刷新权限缓存使其立即生效。
总结: 通过创建专属用户并授予最小必要权限的原则,可以极大地提升MySQL数据库系统的安全性。
MYSQL的访问
1. mysql客户端访问
对于MYSQL,我们可以使用本地mysql客户端进行登录访问;
但MYSQL也是一个网络服务,我们也可以通过远端来登录MYSQL。(在创建用户是指明的登录主机)
2. C语言访问
这里,我们也可以使用编程语言,使用第三方库来访问MYSQL数据库。
这里就使用MYSQL CAPI来访问msyql数据库
mysql_get_client_info:
mysql_get_client_info:可以获取当前mysql版本信息,调用一下该方法来验证是否引入MSYQL库成功
#include <stdio.h>
#include <mysql/mysql.h>
int main()
{
printf("mysql client vesion : %s\n",mysql_get_client_info());
return 0;
}
MYSQL相关接口:
mysql_init :
MYSQL *mysql_init(MYSQL *mysql);
这里mysql_init初始化成功会给我们返回一个MYSQL*类型指针,指向初始化完成的MYSQL对象。
这里
MYSQL就向FILE一样,是描述数据库相关数据的结构体。
参数:参数mysql表示在初始化(创建)时,对MYSQL的约束条件;默认传nullptr/NULL即可。
mysql_real_connect :
初始化完,获取数据库对象之后,就要链接数据库:
MYSQL *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 clientflag);
在链接数据库时,要指明链接哪个数据库mysql;
mysql也是一套网络服务(基于TCP/IP)数据库,在连接时就要指明要链接数据库的主机(本地可以传localhost或者127.0.0.1)、
用户名user、数据库名db、端口号port(默认是3306)、unix_socket(传NULL表示默认),clientflag客户端标识,0表示默认。
返回值
- 如果建立链接成功,就返回
MYSQL*句柄,也就是第一个参数。 - 如果建立链接失败,就返回
NULL。
#include <iostream>
#include <mysql/mysql.h>
int main()
{
MYSQL* mysql = mysql_init(NULL);
if(mysql_real_connect(mysql,"127.0.0.1","lxb","123456","test",3306,NULL,0) == NULL)
{
std::cout<<"connect error"<<std::endl;
return -1;
}
std::cout<<"connect su***ess"<<std::endl;
return 0;
}
mysql_query :
int mysql_query(MYSQL *mysql, const char *q);
参数 :
mysql:表示执行MYSQl结构的指针(句柄)
q:表示要执行的SQL语句
返回值:
返回0表示执行成功,否则就是执行失败。
#include <iostream>
#include <mysql/mysql.h>
int main()
{
MYSQL *mysql = mysql_init(NULL);
if (mysql_real_connect(mysql, "127.0.0.1", "lxb", "hxr040920", "test", 3306, NULL, 0) == NULL)
{
return -1;
}
std::string sql = "insert into stu value (1, '帅哥')";
int ret = mysql_query(mysql, sql.c_str());
if (ret != 0)
std::cout << "mysql_query error" << std::endl;
else
std::cout<<"mysql_query su***ess"<<std::endl;
return 0;
}
获取执行结果
我们可以通过mysql_query向mysql下发指令,如果是插入/更新/删除数据,我们只需要知道是否执行成功即可;
那如果执行select查询语句呢?如何获取查询到的结果呢?
1. 获取MYSQL_RES
如果调用selet语句成功,我们可以使用mysql_store_result来获取查询到的结果
MYSQL_RES *mysql_store_result(MYSQL *mysql);
执行完select语句之后,执行结果是在MYSQl结构中的,而mysql_store_result就可以读取MYSQL中的结果,并且将结果构建成MYSQL_RES结构并返回。
mysql_store_result会调用MYSQL变量中的st_mysql_methods中的read_rows函数指针来获取查询的结构。查询完就会返回
MYSQL_RES这样的一个变量,用来保存查询的结果(malloc一片空间来存储查询的数据,记得free,不然会造成内存泄漏)。
在执行完mysql_store_result之后,查询的结果就在其返回的MYSQL_RES变量中了;
2. 读取MYSQL_RES
MYSQL_RES,这里可以简单的看作一个二维数组(在其中存在一个二维数组用来存储查询结果);
这里我们可以调用mysql_num_rows、mysq_num_fields来获取结果的行数和列数:
//获取结果行数 my_ulonglong 就是无符号长整形
my_ulonglong mysql_num_rows(MYSQL_RES *res);
//获取结果列数
unsigned int mysql_num_fields(MYSQL_RES *res);
获取了结果的行数和列数,我们还要获取列名和数据:
获取列名
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);
mysql_fetch_fields获取列名,返回一个MYSQL_FIELD变量,可以像访问一维数组那样访问它。
#include <iostream>
#include <mysql/mysql.h>
int main()
{
MYSQL *mysql = mysql_init(NULL);
if (mysql_real_connect(mysql, "127.0.0.1", "lxb", "hxr040920", "test", 3306, NULL, 0) == NULL)
{
return -1;
}
std::string sql = "select * from stu";
int n = mysql_query(mysql, sql.c_str());
if (n != 0)
std::cout << "mysql_query error" << std::endl;
else
std::cout << "mysql_query su***ess" << std::endl;
// 获取查询结果
MYSQL_RES *res = mysql_store_result(mysql);
// 获取行、列
my_ulonglong rows = mysql_num_rows(res);
unsigned int fields = mysql_num_fields(res);
MYSQL_FIELD *field = mysql_fetch_field(res);
for (int i = 0; i < fields; i++)
{
//输出列名
std::cout << field[i].name << " ";
}
std::cout << std::endl;
return 0;
}
获取数据:
要获取查询到的内容,这里可以调用mysql_fetch_row:
MYSQL_ROW mysql_fetch_row(MYSQL_RES* result);
这里mysql_fecth_row读取一行数据,返回一个MYSQL_ROW变量,可以当作一维数组来访问。
#include <iostream>
#include <mysql/mysql.h>
int main()
{
MYSQL *mysql = mysql_init(NULL);
if (mysql_real_connect(mysql, "127.0.0.1", "lxb", "hxr040920", "test", 3306, NULL, 0) == NULL)
{
return -1;
}
std::string sql = "select * from stu";
int n = mysql_query(mysql, sql.c_str());
if (n != 0)
std::cout << "mysql_query error" << std::endl;
else
std::cout << "mysql_query su***ess" << std::endl;
// 获取查询结果
MYSQL_RES *res = mysql_store_result(mysql);
// 获取行、列
my_ulonglong rows = mysql_num_rows(res);
unsigned int fields = mysql_num_fields(res);
// 获取查询结果
MYSQL_ROW line;
for (int i = 0; i < rows; i++)
{
line = mysql_fetch_row(res);
for (int j = 0; j < fields; j++)
{
std::cout << line[j] << " ";
}
std::cout << std::endl;
}
return 0;
}
mysql_close
在使用完MYSQL之后,要记得关闭连接;(就像使用FILE一样,使用完之后要关闭文件);
void mysql_close(MYSQL* sock);
此外,MYSQL还支持事务相关的接口,这里就不演示了
3. MYSQL workbench
这是一款MYSQL官方的图形化界面:
官方下载链接:MySQL :: Download MySQL Workbench
[外链图片转存中…(img-Tyg0ebUd-1762932148747)]
mysql_close
在使用完MYSQL之后,要记得关闭连接;(就像使用FILE一样,使用完之后要关闭文件);
void mysql_close(MYSQL* sock);
此外,MYSQL还支持事务相关的接口,这里就不演示了
3. MYSQL workbench
这是一款MYSQL官方的图形化界面:
官方下载链接:MySQL :: Download MySQL Workbench
在windows中安装完MYSQL WorkBench后,连接指定IP地址、端口号,用户名、密码即可连接数据库。
本篇文章到这里就结束了,感谢支持
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.***/developer/support-plan?invite_code=2oul0hvapjsws