Linux——MySQL用户管理与链接

视图

视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。视图的数据变化会影响到基表,基表的数据变化也会影响到视图。

基本使用

创建视图:

create view 视图名 as select语句;

其实就相当于将要查询的列形成一个新的表;
在这里插入图片描述
在这里插入图片描述
并且修改了视图,对基表数据有影响:
在这里插入图片描述
修改了基表,对视图有影响:
在这里插入图片描述
删除视图:

drop view 视图名;

在这里插入图片描述
视图在实际当中用的不多。

视图规则和限制

与表一样,必须唯一命名(不能出现同名视图或表名)。
创建视图数目无限制,但要考虑复杂查询创建为视图之后的性能影响。
视图不能添加索引,也不能有关联的触发器或者默认值。
视图可以提高安全性,必须具有足够的访问权限。
order by 可以用在视图中,但是如果从该视图检索数据 select 中也含有 order by ,那么该视图中的 order by 将被覆盖。
视图可以和表一起使用。

用户管理

如果我们只能使用root用户,这样存在安全隐患。这时,就需要使用MySQL的用户管理。

用户

用户信息

MySQL中的用户,都存储在系统数据库mysql的user表中。
在这里插入图片描述
字段解释:

host: 表示这个用户可以从哪个主机登陆,如果是localhost,表示只能从本机登陆
user: 用户名
authentication_string: 用户密码通过password函数加密后的
*_priv: 用户拥有的权限

基础操作

创建用户

create user ‘用户名’@‘登陆主机/ip’ identified by ‘密码’;
@后面如果是%,说明可以进行任意地点登录,允许远端登录,本地登录。

在这里插入图片描述
删除用户

drop user ‘用户名’@‘主机名’

修改用户密码
自己改自己密码:

set password=password(‘新的密码’);

root用户修改指定用户的密码:

set password for ‘用户名’@‘主机名’=password(‘新的密码’);

数据库的权限

首先了解flush:
FLUSH命令用于管理服务器内部状态,包括清除缓存、重新加载配置或刷新日志等,确保操作生效。其常见用途及示例如下:

清除缓存/缓冲区:释放内存中的临时数据,避免过时信息影响查询。
重新加载配置:使某些配置更改立即生效,无需重启服务。
维护日志文件:安全切换日志文件,便于备份或归档。

MySQL数据库提供的权限列表:

权限上下文
CREATECreate_priv数据库、表或索引
DROPDrop_priv数据库或表
GRANT OPTIONGrant_priv数据库、表或保存的程序
REFERENCESReferences_priv数据库或表
ALTERAlter_priv
DELETEDelete_priv
INDEXIndex_priv
INSERTInsert_priv
SELECTSelect_priv
UPDATEUpdate_priv
CREATE VIEWreate_view_priv视图
SHOW VIEWShow_view_priv视图
ALTER ROUTINEAlter_routine_priv保存的程序
CREATE ROUTINECreate_routine_priv保存的程序
EXECUTEExecute_priv保存的程序
EILEFile_priv服务器主机上的文件访问
CREATE TEMPORARY TABLESCreate_tmp_table_priv服务器管理
LOCK TABLESLock_tables_priv服务器管理
CREATE USERCreate_user_priv服务器管理
PROCESSProcess_priv服务器管理
RELOADReload_priv服务器管理
REPLICATION CLIENTRepl_client_priv服务器管理
REPLICATION SLAVERepl_slave_priv服务器管理
SHOW DATABASESShow_db_priv服务器管理
SHUTDOWNShutdown_priv服务器管理
SUPERSuper_priv服务器管理

给用户授权

刚创建的用户没有任何权限。需要给用户授权。

grant 权限列表 on 库.对象名 to ‘用户名’@‘登陆位置’ [identified by ‘密码’]

权限列表,多个权限用逗号分开:

grant select on …
grant select, delete, create on …
grant all [privileges] on … – 表示赋予该用户在该对象上的所有权限
*. : 代表本系统中的所有数据库的所有对象(表,视图,存储过程等)
库. : 表示某个数据库中的所有数据对象(表,视图,存储过程等)
identified by可选。 如果用户存在,赋予权限的同时修改密码,如果该用户不存在,就是创建用户

在这里插入图片描述
左侧是ROOT用户,右侧是新创建的mfc用户,发现mfc用户只能查看到一个表,这是因为mfc没有权限查看ROOT用户创建的表。
在这里插入图片描述
在这里插入图片描述
给予权限之后就可以看到对应的数据库了。
特定用户现有查看权限

show grants for ‘用户名’@‘%’;

在这里插入图片描述

回收权限

revoke 权限列表 on 库.对象名 from ‘用户名’@‘登陆位置’;

在这里插入图片描述

C/C++进行MySQL链接

首先先创建一个链接专属的账户:
在这里插入图片描述
尽量不要用@’%‘。
创建一个专属的数据库并且给予权限。
在这里插入图片描述

Connector/C 使用

其中 include 包含所有的方法声明, lib 包含所有的方法实现(打包成库)
尝试链接mysql client
通过 mysql_get_client_info() 函数,来验证我们的引入是否成功

#include <stdio.h>
#include <mysql/mysql.h>
int main()
{
    printf("mysql client Version: %s\n", mysql_get_client_info());
    return 0;
}

在这里插入图片描述
这里证明将库引入了。

mysql接口介绍

初始化mysql_init()

要使用库,必须先进行初始化!

MYSQL *mysql_init(MYSQL *mysql)

在这里插入图片描述
在这里插入图片描述
这里和文件一样,要记得关闭
在这里插入图片描述

链接数据库mysql_real_connect

初始化完毕之后,必须先链接数据库,在进行后续操作。(mysql网络部分是基于TCP/IP的)

MYSQL *mysql_real_connect(MYSQL *mysql,//初始化的返回值
                   const char *host,//主机IP
                   const char *user,//账户
                   const char *passwd,//密码
                   const char *db,//要连接哪个数据库
                   unsigned int port,//数据库端口号
                   const char *unix_socket,//Unix socket 路径(若为 NULL 则使用默认值)
                   unsigned long client_flag)// 客户端连接标志(通常为 0)
//建立好链接之后,获取英文没有问题,如果获取中文是乱码:
//设置链接的默认字符集是utf8,原始默认是latin1
mysql_set_character_set(myfd, "utf8");

第一个参数 MYSQL是 C api中一个非常重要的变量(mysql_init的返回值),里面内存非常丰富,有port,dbname,charset等连接基本参数。它也包含了一个叫 st_mysql_methods的结构体变量,该变量里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。mysql_real_connect函数中各参数,基本都是顾名思意。

#include <iostream>
#include <mysql/mysql.h>
#include <string>
using namespace std;
const string host = "127.0.0.1";
const string user = "connect";
const string passwd = "bossaa1s";
const string db = "connect";
const unsigned int port = 3306;
int main()
{
    //printf("mysql client Version: %s\n", mysql_get_client_info());
    MYSQL *my = mysql_init(nullptr);
    if(my == nullptr)
    {
        cerr << "init MYSQL error" << endl;
        return 1;
    }
    if(mysql_real_connect(my,host.c_str(),user.c_str(),passwd.c_str(),db.c_str(),port,NULL,0) == nullptr)
    {
        cerr << "connect MYSQL error" <<endl;
        return 2;
    }
    mysql_set_character_set(my, "utf8");
    cout << "connect success" <<endl;
    mysql_close(my);
    return 0;
}

在这里插入图片描述
这里记得要启动mysql的服务器才能启动成功。

下发mysql命令mysql_query

int mysql_query(MYSQL *mysql, const char *q);

第二个参数为要执行的sql语句,如“select * from table”。
先创建一个表:
在这里插入图片描述
然后可以通过这个方式查询连接数据库的信息和状态:
在这里插入图片描述
然后让刚才的程序sleep十秒钟。
在这里插入图片描述
红框是我们C++的方式连接的数据库,蓝色框是sleep运行的时间。
然后进入正题:

#include <iostream>
#include <mysql/mysql.h>
#include <string>
#include <unistd.h>
using namespace std;
const string host = "127.0.0.1";
const string user = "connect";
const string passwd = "bossaa1s";
const string db = "connect";
const unsigned int port = 3306;
int main()
{
    //printf("mysql client Version: %s\n", mysql_get_client_info());
    MYSQL *my = mysql_init(nullptr);
    if(my == nullptr)
    {
        cerr << "init MYSQL error" << endl;
        return 1;
    }
    if(mysql_real_connect(my,host.c_str(),user.c_str(),passwd.c_str(),db.c_str(),port,NULL,0) == nullptr)
    {
        cerr << "connect MYSQL error" <<endl;
        return 2;
    }
    mysql_set_character_set(my, "utf8");
    string sql;
    while(1)
    {
        cout << "MySQL>>>";
        if(!getline(cin,sql)|| sql == "quit") 
        {
            cout << "bye bye" <<endl;
            break;
        }
        
        int n = mysql_query(my,sql.c_str());
        if(n == 0) cout << sql << "success:" << n << endl;
        else cerr << mysql_error(my) << endl;
    }
    
    cout << "connect success" <<endl;
    mysql_close(my);
    return 0;
}

在这里插入图片描述
在这里插入图片描述
而且这里的命令行其实可以不用带分号结尾的。
在这里插入图片描述

在这里插入图片描述
这里的插入增删改不必担心,因为有事务的存在,保证了原子性和回滚。
但是select * from table语句就有一些细节了,这个后面再说。

获取执行结果mysql_store_result

sql执行完以后,如果是查询语句,我们当然还要读取数据,如果update,insert等语句,那么就看下操作成功与否即可。我们来看看如何获取查询结果: 如果mysql_query返回成功,那么我们就通过mysql_store_result这个函数来读取结果。原型如下:

MYSQL_RES *mysql_store_result(MYSQL *mysql);

该函数会调用MYSQL变量中的st_mysql_methods中的 read_rows 函数指针来获取查询的结果。同时该函数会返回MYSQL_RES 这样一个变量,该变量主要用于保存查询的结果。同时该函数malloc了一片内存空间来存储查询过来的数据,所以我们一定要记的 free(result),不然是肯定会造成内存泄漏的。 执行完mysql_store_result以后,其实数据都已经在MYSQL_RES 变量中了,下面的api基本就是读取MYSQL_RES 中的数据。
在这里插入图片描述
那么这个结构究竟细节是什么呢?
首先清楚,这是从MYSQL转储到MYSQL_RES中的,我们拿到的每一行每一列数据都要有对应的空间进行存储。(mysql读取出来的数据全都当成字符串)
在这里插入图片描述

其实MYSQL_RES就是一个类似二级指针数组一样。
那么怎么去拿取到这个结构体当中的结果呢?
获取结果行数mysql_num_rows

my_ulonglong mysql_num_rows(MYSQL_RES *res);

获取结果列数mysql_num_fields

unsigned int mysql_num_fields(MYSQL_RES *res);
#include <iostream>
#include <mysql/mysql.h>
#include <string>
#include <unistd.h>
using namespace std;
const string host = "127.0.0.1";
const string user = "connect";
const string passwd = "bossaa1s";
const string db = "connect";
const unsigned int port = 3306;
int main()
{
    MYSQL *my = mysql_init(nullptr);
    if(my == nullptr)
    {
        cerr << "init MYSQL error" << endl;
        return 1;
    }
    if(mysql_real_connect(my,host.c_str(),user.c_str(),passwd.c_str(),db.c_str(),port,NULL,0) == nullptr)
    {
        cerr << "connect MYSQL error" <<endl;
        return 2;
    }
    mysql_set_character_set(my, "utf8");
    string sql = "select * from user";
    int n = mysql_query(my,sql.c_str());
    if(n == 0) cout << sql << "success:" << n << endl;
    else 
    {
        cerr << mysql_error(my) << endl;
        return 3;
    }
    MYSQL_RES * res = mysql_store_result(my);
    if(res == nullptr)
    {
        cerr << "mysql_store_result error" <<endl;
        return 4;
    }
    my_ulonglong rows = mysql_num_rows(res);//获取行
    unsigned int fields = mysql_num_fields(res);//获取列

    cout << "行" << rows << endl;
    cout << "列" << fields << endl;
    cout << "connect success" <<endl;
    mysql_close(my);
    return 0;
}

在这里插入图片描述
获取列名mysql_fetch_fields

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);

获取结果内容mysql_fetch_row

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
#include <iostream>
#include <mysql/mysql.h>
#include <string>
#include <unistd.h>
using namespace std;
const string host = "127.0.0.1";
const string user = "connect";
const string passwd = "bossaa1s";
const string db = "connect";
const unsigned int port = 3306;
int main()
{
    MYSQL *my = mysql_init(nullptr);
    if(my == nullptr)
    {
        cerr << "init MYSQL error" << endl;
        return 1;
    }
    if(mysql_real_connect(my,host.c_str(),user.c_str(),passwd.c_str(),db.c_str(),port,NULL,0) == nullptr)
    {
        cerr << "connect MYSQL error" <<endl;
        return 2;
    }
    mysql_set_character_set(my, "utf8");
    string sql = "select * from user";
    int n = mysql_query(my,sql.c_str());
    if(n == 0) cout << sql << "success:" << n << endl;
    else 
    {
        cerr << mysql_error(my) << endl;
        return 3;
    }
    MYSQL_RES * res = mysql_store_result(my);
    if(res == nullptr)
    {
        cerr << "mysql_store_result error" <<endl;
        return 4;
    }
    my_ulonglong rows = mysql_num_rows(res);//获取行
    unsigned int fields = mysql_num_fields(res);//获取列

    cout << "行" << rows << endl;
    cout << "列" << fields << endl;
//属性
    MYSQL_FIELD *fields_array = mysql_fetch_fields(res);
    for(int i = 0;i < fields;i++)
    {
        cout << fields_array[i].name <<"\t"; 
    }
    cout <<endl;
//内容
    for(int i = 0;i < rows;i++)
    {
        MYSQL_ROW row = mysql_fetch_row(res);
        for(int j = 0;j < fields;j++)
        {
            cout << row[j] << "\t";//*(row+j)
        }
        cout << endl;
    }

    cout << "connect success" <<endl;
    mysql_close(my);
    return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ℳℓ白ℳℓ夜ℳℓ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值