MySQL——视图 && 用户管理 && 语言访问

发布于:2025-06-06 ⋅ 阅读:(24) ⋅ 点赞:(0)

目录

视图

用户管理

数据库权限

访问

准备工作

使用函数

mysql界面级工具

         连接池


视图

        这里的视图与事务中的读视图是两个不同的概念:视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。视图的数据变化会影响到基表,基表的数据变化也会影响到视图

        创建视图

        修改视图后对原表产生影响,修改原表会对视图产生影响

        原表数据发生了改变

        删除视图

                总结:使用视图时注意以下几点:

  • 与表一样,必须唯一命名(不能出现同名视图或表名);
  • 创建视图数目无限制,但要考虑复杂查询创建为视图之后的性能影响;
  • 视图不能添加索引,也不能有关联的触发器或者默认值;
  • 视图可以提高安全性,必须具有足够的访问权限;(它能从原表中把私密数据(如密码去除)后展示,修改视图也要影响原表)
  • order by 可以用在视图中,但是如果从该视图检索数据 select 中也含有 order by ,那么该视图中的 order by 将被覆盖(但版本不同不一定会受影响)

用户管理

        与Linux一样:mysql也是要进行多用户进行管理,因为多用户使用存在着安全问题

        

        用户数据保存在 mysql 库中

        可能你在之前配置时mysql登录时root是无密码登录的,也就是: skip-grant-tables 模式,此时设置密码会报错,首次对表user 操作要先权限刷新才能设置/修改密码

        创建用户后也是要刷新权限后另一个客户端才能用新用户进行登录

        另一端登录成功

        @后面跟着用户登录的环境,localhost 代表他只能在本地进行登录;% 代表他能够在任意环境下进行登录 

         用户觉得碍眼可以把他进行删除

        此时另一端就登不上了

数据库权限

        mysql提供了很多权限

        登录root用户,给zzj用户emp的select权限   

         zzj用户就能看到scott数据库,但进入后只能看到emp

        只能继续select操作

        如果想要emp全部的权限,则root要这么干

         此时zzj就能进行操作了

        觉得zzj不能进行emp的如何操作,则可以把权限回收了

        此时zzj连scott库都看不到了

语言访问

        mysql是指令级别进行操作,而语言要想支持操作数据库,mysql就必须为我们提供各种库名与头文件,让我们在语言级别实现数据库的基本操作;如果之前在配置mysql时选择的是yum源配置mysql后通过yum源下载的mysql-community-server,那么就代表库也帮你下完了,不用你在进行去官网下载库在导进文件中了,但默认没给我们提供头文件这个需要自己下载mysql的devel文件

sudo yum install mysql-community-devel

        下载完后第一件是就是写代码来验证环境是否配置成功了

#include<iostream>
#include<mysql/mysql.h>
using namespace std;
int main()
{
    cout<<"mysql version: "<<mysql_get_client_info()<<endl;
    return 0;
}

        进行编译时要指明对应链接的库,因为第三方库g++默认是不会自己找到即使它存在

g++ test.cc -L/lib64/mysql -l mysqlclient

        正确打印出mysql版本号就说明环境没问题

准备工作

        使用root账号创建空数据库并给普通用户(未来登录时使用它进行登录)库的所有操作权

        查看普通用户视角操作库

使用函数

        先进行数据库对象mysql初始化,接着链接时要设置各种配置信息(用户名,密码,端口号...),使用后对mysql进行关闭

#include<iostream>
#include<string>
#include<unistd.h>
#include<mysql/mysql.h>

const std::string host="localhost";
const std::string user="zzj";
const std::string password="0628";
const std::string database="test_conn";
unsigned int port=3306;


int main()
{
    //初始化
    MYSQL *mq=mysql_init(nullptr);
    if(mq==nullptr)
    {
        std::cerr<<"mysql init fail"<<std::endl;
        return 1;
    }
    //远程链接数据库
    MYSQL* my=mysql_real_connect(mq,host.c_str(),user.c_str(),
    password.c_str(),database.c_str(),port,nullptr,0);
    if(my==nullptr)
    {
        std::cerr<<"mysql connect fail"<<std::endl;
        return 1;
    }
    //添加等待进行观察
    sleep(10);
    std::cout<<"sucess"<<std::endl;

    //使用完后要关闭
    mysql_close(mq);
    return 0;
}

        运行程序后,我们确实通过上层访问到了数据库

         使用 mysql_query 函数将我们输入的字符串mysql语句在数据库内执行,就可以制作出一个简易版的mysql客户端

#include<iostream>
#include<string>
#include<unistd.h>
#include<mysql/mysql.h>

const std::string host="localhost";
const std::string user="zzj";
const std::string password="0628";
const std::string database="test_conn";
unsigned int port=3306;


int main()
{
    //初始化
    MYSQL *mq=mysql_init(nullptr);
    if(mq==nullptr)
    {
        std::cerr<<"mysql init fail"<<std::endl;
        return 1;
    }
    //远程链接数据库
    MYSQL* my=mysql_real_connect(mq,host.c_str(),user.c_str(),
    password.c_str(),database.c_str(),port,nullptr,0);
    if(my==nullptr)
    {
        std::cerr<<"mysql connect fail"<<std::endl;
        return 1;
    }
    std::string mysql;
    while(true)
    {
        std::cout<<"Mysql> ";
        std::getline(std::cin,mysql);
        if(mysql=="quit" || mysql.empty())
        {
            std::cout<<"Bye"<<std::endl;
            break;
        }
        mysql_query(my,mysql.c_str());
    }

    //使用完后要关闭
    mysql_close(mq);
    return 0;
}

        我们输入在程序运行时输入的mysql语句成功地执行了

        但在这里有一个问题:怎么中文输入的字符串出现了乱码? 之前在配置mysql时默认是utf-8 支持汉字啊;问题不在这里,而在建立链接后访问数据库时它默认使用字符集latin1去访问的,需要使用 mysql_set_character_set() 设置下字符串下即可

         不用;语句也可以执行成功(函数默认只能执行一条语句,防止SQL注入);现在已经可以继续增删改操作了,查操作虽然也可以,但它执行结果后要给我们打印出数据信息才是我们要的;

        边框可以打印,要的是属性名与下面对应的内容,要怎么实现呢?

        先用 MYSQL_RES* mysql_store_result() 保存结果的所有数据,它是char**[] 数组;接着使用mysql_num_rows(MYSQL_RES *) 和 mysql_num_fields(MYSQL_RES *) 获取到行数与列数,注意传入的参数是前面的函数返回对象;获取总属性名使用 mysql_fetch_fields(MYSQL_RES *),它是 char*[]数组,打印时要根据列数才能打印完整;内容提供 mysql_fetch_row(MYSQL_RES *) 它也是char*[]数组,不过它只保存着第一行的内容,下次调用就返回第二行的内容...也是要根据行数与列数才能打印完整内容

#include<iostream>
#include<string>
#include<unistd.h>
#include<mysql/mysql.h>

const std::string host="localhost";
const std::string user="zzj";
const std::string password="0628";
const std::string database="test_conn";
unsigned int port=3306;


int main()
{
    //初始化
    MYSQL *mq=mysql_init(nullptr);
    if(mq==nullptr)
    {
        std::cerr<<"mysql init fail"<<std::endl;
        return 1;
    }
    //远程链接数据库
    MYSQL* my=mysql_real_connect(mq,host.c_str(),user.c_str(),
    password.c_str(),database.c_str(),port,nullptr,0);
    if(my==nullptr)
    {
        std::cerr<<"mysql connect fail"<<std::endl;
        return 1;
    }
    //设置utf-8字符集
    mysql_set_character_set(mq,"utf8");

    std::string mysql="select *from people";
    mysql_query(my,mysql.c_str());
    //获取结果的所有数据保存在MYSQL_RES对象中
    MYSQL_RES* res=mysql_store_result(my);
    //获取内容行和列(在MYSQL_RES中获取)
    int rows=mysql_num_rows(res);
    int fields=mysql_num_fields(res);
    //打印属性.属性相关保存在MYSQL_FIELD对象中
    MYSQL_FIELD *fields_at=mysql_fetch_fields(res);
    for(int i=0;i<fields;i++)
    {
        std::cout<<fields_at[i].name<<' ';
    }
    std::cout<<std::endl;
    //打印内容
    for(int i=0;i<rows;i++)
    {
        //相等与迭代器:调用一次跳转到下一行
        MYSQL_ROW row_content=mysql_fetch_row(res);
        for(int j=0;j<fields;j++)
        {
            std::cout<<row_content[j]<<' ';
        }
        std::cout<<std::endl;
    }
    //使用完后是否结果集
    mysql_free_result(res);
    //使用完后要关闭
    mysql_close(mq);
    return 0;
}

         程序运行结果

        以上操作都是mysql为了支持C语言操作数据库提供的各种函数,像C++,Java也有自己的mysql库,需要查找文档后自行测试使用

mysql界面级工具

        mysql也支持使用界面的方式来连接数据库进行使用,以Winodws为例,先到官网下载:Download MySQL Workbench;在数据库中准备一个用户,host设置为‘%’表示任何地方都能连接;还要在my.cnf配置中添加:

bind-address=0.0.0.0
skip-networking = OFF

        下载完软件后,点击+填上对应的数据库用户信息

        填写完再次点击填好的信息就登录进来了(但我这边给用户开通了全部权限,在本地数据库上可以修改数据,但在图像化界面里修改不了数据,是BUG?)

连接池

        在正式的应用场景中,要怎么设计让使用者使用sql语句高效地在语言层面上执行呢?与前面数据的线程池类似:数据一个类,类中有线程和任务队列的成员变量,让每个线程先跑起来,把mysql对象初始化,等待任务到来;使用sql语句准备好后,把sql语句包装成任务队列中的对象:里面保存着sql语句字符串,相关执行的函数,标记位;任务到来后唤醒线程,让其中一个线程拿着一个任务执行mysql_query()函数;如果是select执行要返回处理结果后返回,就可以把方法绑定后传给线程,线程根据标记位执行回调函数后把处理完的数据给我们返回

以上便是全部内容,有问题欢迎在评论区指正,感谢观看! 


网站公告

今日签到

点亮在社区的每一天
去签到