QT C++实践|超详细数据库的连接和增删改查操作|附源码

0:前言

🪧 什么情况需要数据库?

  • 1 大规模的数据需要处理(比如上千上万的数据量)
  • 2 需要把数据信息存储起来,无论是本地还是服务上,而不是断电后数据信息就消失了。

如果不是上面的原因化,一般可以使用数组来处理。

 🪧一般常使用的数据库驱动是MYSQLQSQLITE。二者区别在于,前者用于服务器存储信息,后者用于本地存储信息。并且QSQLITE主要用于嵌入式,占用资源非常低,占用内存小,通常几百k就搞定。’

这里博主因为对MySQL熟悉一些,就使用MySQL来进行数据库的连接

一、Mysql的安装

因为我们项目的方案是程序的运行以及相关数据的存储都在一台主机上,所以不论打不打包。首先要在主机上安装Mysql的。Mysql的安装教程我参考的是这个:MySQL安装和配置教程(超详细版本)

安装好后,利用命令行或其他工具在MySQL中创建一个存储项目数据的数据库,方便之后使用QT用代码对数据库进行连接、建表和增删改查的操作:

  • Win+r打开cmd:输入命令“mysql -u root -p”,按下回车键
  • 输入MySQL密码,按下回车键
  • 创建数据库
create database [if not exists] 数据库名 [default charset 字符集] [collate 排序规则];

注意:不要忘记末尾的分号

二、通过ODBC连接MySQL数据库

官方解释:
ODBC(Open Database Connectivity,开放数据库互连)提供了一种标准的API(应用程序编程接口)方法来访问数据库管理系统(DBMS)。这些API利用SQL来完成其大部分任务。ODBC本身也提供了对SQL语言的支持,用户可以直接将SQL语句送给ODBC。ODBC的设计者们努力使它具有最大的独立性和开放性:与具体的编程语言无关,与具体的数据库系统无关,与具体的操作系统无关。
简单的说就是我的qt中含有ODBC的驱动:
在这里插入图片描述
所以利用ODBC去使用MySQL的数据库

2.1:下载ODBC

官网

在这里插入图片描述

选择和qt编译器相同的字节比如我的qt使用的是64字节的

下载完成后,点卡下载下来的.msi文件并运行:

在这里插入图片描述
下载一直点击next
在这里插入图片描述

选择custom,表示自定义安装(以便修改安装位置)

在这里插入图片描述
在这里插入图片描述

最后一直点击next然后再install即可,等待安装好后即可。

安装好之后,关闭窗口,搜索ODBC,并运行程序:
在这里插入图片描述

2.2:使用ODBC连接MySQL数据库

添加MySQL的DSN

在这里插入图片描述

红色的可以随便填,是自己对于ODBC驱动的描述,粉色的是MySQL的用户名和密码,数据库选择你在MySQL中创建的数据库名字即可:
在这里插入图片描述

点击Test,测试是否能够成功连接;如果出现下图说明连接成功

在这里插入图片描述

然后点击应用确定进行添加:
在这里插入图片描述

2.3:qt通过ODBC连接MySQL

现在main.cpp中加入下面代码测试一下能不能在qt中连接成功:

QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");db.setHostName("127.0.0.1");db.setPort(3306);db.setDatabaseName("是你在ODBC中创建的Data source name");db.setUserName("用户名");db.setPassword("密码");bool ok = db.open();if (ok){QMessageBox::information(this, "infor", "success");}else {QMessageBox::information(this, "infor", "open failed");qDebug()<<"error open database because"<<db.lastError().text();}

Tips:这里可能会报错:VS2019 C1083 无法打开包括文件: “QSqlDatabase”

是vs里面项目配置的问题。
看到这个错误应该是没有dll,然后sql很容易想到数据库,所以在qt模块里添加,比较方便。
在这里插入图片描述
在这里插入图片描述

不出意外运行程序可以成功连接:
在这里插入图片描述

之后在主机进行安装时,除了打包程序,应该还需要安装对应的Mysql和ODBC

2.4:qt通过ODBC操作数据库

连接上数据库一般就是使用数据库,进行对数据库的增删改查。
这里有三种方法。

🪧 首先单独建立一个头文件来处理数据库连接,如建立头文件connection.h:

#ifndef CONNECTION_H
#define CONNECTION_H#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QDebug>static bool createConnection(){//连接第一个数据库//QMYSQLQSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "connection1");//需要使用的数据库驱动和联检建立的名称(方便建立多个数据库连接【使用不同的数据库时】区分)db.setHostName("127.0.0.1");//连接地址db.setUserName("root");//数据库账户db.setPassword("root");//密码db.setPort(8889);//端口//test_majiang.dbdb.setDatabaseName("test_majiang");//需要用到的数据库if (!db.open()) {//如果数据库连接失败,则弹出//critical(QWidget *parent, const QString &title,//const QString &text,//QMessageBox::StandardButtons buttons = Ok,//QMessageBox::StandardButton defaultButton = NoButton)QMessageBox::critical(0, "Cannot open database","Unable to establish a database connection", QMessageBox::Cancel);return false;}return true;
}#endif // CONNECTION_H

如果需要移除一个数据库连接,可以使用:

 QSqlDatabase::close();//关闭数据库QSqlDatabase::removeDatabase();//移除该连接

2.4.1:使用QSqlQuery

头文件

#include "connection.h"
#include <QVariant>
#include <QSqlDriver>
#include <QSqlRecord>
#include <QSqlField>
#include <QSqlError>
  • 使用数据库前的准备:
    //创建数据库连接if(!createConnection()) return 1;//返回情况可以替换,视不同情况而定//指定某个数据库连接QSqlDatabase db2 = QSqlDatabase::database("connection1");
  • 开始对数据进行操作:
    首先创建QSqlQuery 对象,然后进行操作。
    QSqlDatabase db2 = QSqlDatabase::database("connection2");QSqlQuery query2(db2);
  • 进行创表和插入值:
   // qDebug() << "connection2:";//创建表,并插入值query2.exec("create table student (id int primary key,""name varchar(20))");query2.exec("insert into student values(0, 'Mike')");query2.exec("insert into student values(1, 'Lili')");query2.exec("insert into student values(2, 'Jame')");
  • 批量处理
    上面的单条插入语句明显比较麻烦,可以使用批量插入数据:
    query2.exec("insert into student(id,name) values(3,'Qinsong')");//单挑操作//名称绑定query2.prepare("insert into student(id, name) values(:id, :name)");int idValue = 4;QString nameValue = "Songjiang";query2.bindValue(":id", idValue);//绑定数据query2.bindValue(":name", nameValue);query2.exec();//执行//位置绑定query2.prepare("insert into student(id, name) values(?, ?)");int idValue2 = 5;QString nameValue2 = "LingChong";query2.addBindValue(idValue2);//绑定数据query2.addBindValue(nameValue2);if(!query2.execBatch()) qDebug() <<"位置绑定:" <<query2.lastError() <<endl;//如果执行不成功执行//批量处理query2.prepare("insert into student(id, name) values(?,?)");QVariantList ids;ids << 6 << 7 << 8;query2.addBindValue(ids);QVariantList names;names << "Qinghua" << "Nanda" << "Zhongkeda";query2.addBindValue(names);if(!query2.execBatch()) qDebug() << query2.lastError()<< endl;
  • 进行查询并输出查询结果:
    query2.exec("select * from student");//执行sql语句while(query2.next()){qDebug()<< query2.value(0).toInt() << query2.value(1).toString();}
  • 查看数据驱动支持特性
    查看当前数据库是否是支持某特性,比如当前记录的索引数(即结果条数):
    int numRows;if(db2.driver()->hasFeature(QSqlDriver::QuerySize)){//是否该特性qDebug()<< "has feature:query size";numRows = query2.size();}else{qDebug() << "no feature:query size";query2.last();numRows = query2.at() + 1;//使用at,需要之前使用quey2.next()遍历所有select搜索后的结果,而使用query2.size()则不需要}//此处执行上面的查询操作,下面的操作才有意义qDebug() << "row number: " << numRows;//指向索引为1的记录,即第二条记录query2.seek(1);//返回当前索引值qDebug() << "current index:" << query2.at();//获得当前行的记录QSqlRecord record = query2.record();//获得记录中"id"和"name"两个字段的值int id = record.value("id").toInt();QString name = record.value("name").toString();qDebug() <<"id" << id << "name:" <<name;//获得索引为1的字段,即第二个字段QSqlField field = record.field(1);//输出字段名和字段值,结果为"name"和"MaLiang"qDebug() << "second field:" << field.name()<< "field value:" << field.value().toString();
  • 事务(使数据操作变为原子性)
    如果中间有一步sql操作执行出错,则全部sql操作都不执行。
    QSqlDatabase db2 = QSqlDatabase::database("connection2");QSqlDatabase::database().transaction();//开始(类似于mutex线程锁)QSqlQuery query(db2);//此语句必须在上面一条语句的后面//执行sql操作QSqlDatabase::database().commit();//结束

2.4.2:使用QSqlQueryModel查询模型

优势:

  • 这是基于sql查询的只读模型,编写sql语句变得容易。

文件头:

#include <QSqlQueryModel>

核心代码:

  QSqlDatabase db = QSqlDatabase::database("connection1");QSqlQueryModel *model = new QSqlQueryModel(this);model->setQuery("select * from student", db);model->setHeaderData(0, Qt::Horizontal, tr("学号"));model->setHeaderData(1, Qt::Horizontal, tr("姓名"));model->setHeaderData(2, Qt::Horizontal, tr("课程"));QTableView *view = new QTableView(this);view->setModel(model);setCentralWidget(view);

2.4.3:使用QSqlTableModel表格模型⭐

先上结果
在这里插入图片描述

优势:

  • 编译的代码很容易适应其他的数据源,例如后面如果要使用xml文件来存储数据,只需要更换数据模型。

  • 提供了一次只能操作一个sql表的读/写模型,可以浏览和修改独立的sql表,并且只需编写很少的代码,无需了解sql语句。

  • 1 准备
    头文件:

#include <QSqlTableModel>
    QSqlTableModel* model;//创建对象指针
  • 2 进行操作:
    QSqlDatabase db = QSqlDatabase::database("connection1");model = new QSqlTableModel(this, db);//由于在窗口的类中创建对象,因此实例化对象时,使用this指针(指向操作函数的指针)作为父对象model->setTable("student");model->select();//执行//设置编辑策略model->setEditStrategy(QSqlTableModel::OnManualSubmit);//对所有模型改变立即用到数据库ui->tableView->setModel(model);
  • UI设计:
    在这里插入图片描述

  • 对应槽函数:

// 提交修改按钮
void MainWindow::on_pushButton_clicked()
{// 开始事务操作model->database().transaction();if (model->submitAll()) {if(model->database().commit()) // 提交QMessageBox::information(this, tr("tableModel"),tr("数据修改成功!"));} else {model->database().rollback(); // 回滚QMessageBox::warning(this, tr("tableModel"),tr("数据库错误: %1").arg(model->lastError().text()),QMessageBox::Ok);}
}// 撤销修改按钮
void MainWindow::on_pushButton_2_clicked()
{model->revertAll();
}// 查询按钮,进行筛选
void MainWindow::on_pushButton_5_clicked()
{QString name = ui->lineEdit->text();// 根据姓名进行筛选,一定要使用单引号model->setFilter(QString("name = '%1'").arg(name));model->select();
}// 显示全表按钮
void MainWindow::on_pushButton_6_clicked()
{model->setTable("student");model->select();
}// 按id升序排列按钮
void MainWindow::on_pushButton_7_clicked()
{//id字段,即第0列,升序排列model->setSort(0, Qt::AscendingOrder);model->select();}// 按id降序排列按钮
void MainWindow::on_pushButton_8_clicked()
{model->setSort(0, Qt::DescendingOrder);model->select();}
// 删除选中行按钮
void MainWindow::on_pushButton_4_clicked()
{// 获取选中的行int curRow = ui->tableView->currentIndex().row();// 删除该行model->removeRow(curRow);int ok = QMessageBox::warning(this,tr("删除当前行!"),tr("你确定删除当前行吗?"), QMessageBox::Yes, QMessageBox::No);if(ok == QMessageBox::No){ // 如果不删除,则撤销model->revertAll();} else { // 否则提交,在数据库中删除该行model->submitAll();}}
// 添加记录按钮
void MainWindow::on_pushButton_3_clicked()
{// 获得表的行数int rowNum = model->rowCount();int id = 10;// 添加一行model->insertRow(rowNum);model->setData(model->index(rowNum, 0), id);// 可以直接提交//model->submitAll();
}

三、项目实战

connection.h是负责连接数据库和创建表的头文件:

#ifndef CONNECTION_H
#define CONNECTION_H#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QDebug>
#pragma execution_character_set("utf-8"); static bool createConnection() {//连接第一个数据库//QMYSQLQSqlDatabase db = QSqlDatabase::addDatabase("QODBC", "connection1");//需要使用的数据库驱动和联检建立的名称(方便建立多个数据库连接【使用不同的数据库时】区分)db.setHostName("127.0.0.1");//连接地址db.setUserName("root");//数据库账户db.setPassword("55667788");//密码db.setPort(3306);//端口//test.dbdb.setDatabaseName("test");//需要用到的数据库if (!db.open()) {//如果数据库连接失败,则弹出//critical(QWidget *parent, const QString &title,//const QString &text,//QMessageBox::StandardButtons buttons = Ok,//QMessageBox::StandardButton defaultButton = NoButton)QMessageBox::critical(0, "Cannot open database","Unable to establish a database connection", QMessageBox::Cancel);return false;}else {QMessageBox::information(NULL, "infor", "link success");}//下面来创建表//如果MySQL数据库中已经存在同名的表,则下面代码不会执行QSqlQuery query2(db);// qDebug() << "connection2:";
//创建表,并插入值query2.exec("create table student (id int primary key,""name varchar(20))");query2.exec("insert into student values(0, 'Mike')");query2.exec("insert into student values(1, 'Lili')");query2.exec("insert into student values(2, 'Jame')");}#endif // CONNECTION_H

Admin是操作数据库的管理界面:
在这里插入图片描述
Admin.h:

#pragma once#include <QMainWindow>
#include "ui_Admin.h"
#include <QSqlTableModel>
#pragma execution_character_set("utf-8"); class Admin : public QMainWindow
{Q_OBJECTpublic:Admin(QWidget *parent = nullptr);~Admin();QSqlTableModel* model;//创建对象指针private:Ui::AdminClass ui;private slots:void on_add_clicked();void on_modify_clicked();void on_del_clicked();void on_rollback_clicked();void on_show_all_clicked();
};

Admin.cpp:

#include "Admin.h"
#include <qmessagebox.h>
#include <QSqlDatabase>
#include <QMessageBox>
#include <qsqlerror.h>
#include "connection.h"
#include <QSqlTableModel>Admin::Admin(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);if (!createConnection()) {return;}QSqlDatabase db = QSqlDatabase::database("connection1");model = new QSqlTableModel(this, db);//由于在窗口的类中创建对象,因此实例化对象时,使用this指针(指向操作函数的指针)作为父对象model->setTable("student");model->select();//执行QTableView* view = new QTableView;view->setModel(model);// 你可以根据你数据库表的实际列名进行设置QHeaderView* header = view->horizontalHeader();header->setModel(model);header->setSectionResizeMode(QHeaderView::Stretch);// 设置显示名称,从0开始计数model->setHeaderData(0, Qt::Horizontal, tr("列名1"));model->setHeaderData(1, Qt::Horizontal, tr("列名2"));model->setHeaderData(2, Qt::Horizontal, tr("列名3"));//设置编辑策略model->setEditStrategy(QSqlTableModel::OnManualSubmit);//对所有模型改变立即用到数据库ui.tableView->setModel(model);}Admin::~Admin()
{}// 添加记录按钮
void Admin::on_add_clicked()
{// 获得表的行数int rowNum = model->rowCount();int id = 10;// 添加一行model->insertRow(rowNum);model->setData(model->index(rowNum, 0), id);// 可以直接提交//model->submitAll();
}// 删除选中行按钮
void Admin::on_del_clicked()
{// 获取选中的行int curRow = ui.tableView->currentIndex().row();// 删除该行model->removeRow(curRow);int ok = QMessageBox::warning(this, tr("删除当前行!"),tr("你确定删除当前行吗?"), QMessageBox::Yes, QMessageBox::No);if (ok == QMessageBox::No){ // 如果不删除,则撤销model->revertAll();}else { // 否则提交,在数据库中删除该行model->submitAll();}}
// 撤销修改按钮
void Admin::on_rollback_clicked()
{model->revertAll();
}// 提交修改按钮
void Admin::on_modify_clicked()
{// 开始事务操作model->database().transaction();if (model->submitAll()) {if (model->database().commit()) // 提交QMessageBox::information(this, tr("tableModel"),tr("数据修改成功!"));}else {model->database().rollback(); // 回滚QMessageBox::warning(this, tr("tableModel"),tr("数据库错误: %1").arg(model->lastError().text()),QMessageBox::Ok);}
}
// 显示全表按钮
void Admin::on_show_all_clicked() {model->setTable("student");model->select();
}

功能正常:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/709874.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

是谁家的小千金跑出来了?

古典的山树绣花设计 精致典雅&#xff0c;上身立体又轻盈 做了粉绿两色&#xff0c;很适合春天的氛围 春天是个适合外出游玩的季节 穿上这件出游真的超美&#xff0c;日常穿也可 超出片很吸睛&#xff01;

Pytorch学习 day01(Jupyter安装

Jupyter 安装过程中遇到的问题&#xff1a; Anaconda的base环境会自动安装Jupyter&#xff0c;但是如果我们要在其他环境中安装Jupyter&#xff0c;就需要注意&#xff0c;该环境的python版本不能高于3.11&#xff0c;且用以下代码安装&#xff1a; conda install nb_conda_…

齐护ESP32手柄可Arduino编程蓝牙无线游戏手柄Mixly Scratch创客竞赛编程手柄

关于齐护蓝牙手柄 齐护蓝牙手柄&#xff0c;内置蓝牙&#xff0c;专用蓝牙配对码稳定应用&#xff0c;自动无动作后省电休眠&#xff0c;内置锂电池&#xff0c;陀螺仪&#xff0c;双遥杆&#xff08;带按键&#xff09;&#xff0c;及15个多功能按键&#xff0c;人体工艺设计外…

消息中间件之RocketMQ源码分析(二十三)

Broker的关机恢复机制 概述 Broker关机恢复是指恢复CommitLog、Consume Queue、Index File等数据文件。Broker关机分为正常调用命令关机和异常被迫进程终止关机两种情况。恢复过程的设计目标是使正常停止的进程实现零数据丢失&#xff0c;异常停止的进程实现最少量的数据丢失…

Java 数据库面试题解析(中)

10. 事务并发引发的问题&#xff1f;【重点】 脏读&#xff1a;事务A读取了事务B更新的数据&#xff0c;然后B回滚操作&#xff0c;那么A读取到的数据是脏数据。 不可重复读&#xff1a;事务A多次读取同一数据&#xff0c;事务B在事务A多次读取的过程中&#xff0c;对数据作了…

Groovy - 大数据共享搜索配置

数据共享搜索列中配置了搜索列&#xff0c;相应的数据共享接口中也需要支持根据配置的字段搜索&#xff0c;配置实体时&#xff0c;支持搜索的入参code必须是searchKeys&#xff0c;且接口应该是需要支持分页&#xff08;入参必须是 current、pageSize&#xff09;的。current …

Linux系统Docker部署Nexus Maven并实现远程访问本地管理界面

文章目录 1. Docker安装Nexus2. 本地访问Nexus3. Linux安装Cpolar4. 配置Nexus界面公网地址5. 远程访问 Nexus界面6. 固定Nexus公网地址7. 固定地址访问Nexus Nexus是一个仓库管理工具&#xff0c;用于管理和组织软件构建过程中的依赖项和构件。它与Maven密切相关&#xff0c;可…

SpringBoot多数据源配置(MySql、Oracle)

一、依赖 <!-- dynamic-datasource 多数据源--><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId></dependency><!--oracle驱动--><dependency><groupI…

JavaScript高级程序设计

前言 《JavaScript高级程序设计》 第1章——什么是JavaScript DOM将整个页面抽象为一组分层节点。 BOM用于支持访问和操作浏览器的窗口。 第2章——HTML中的JavaScript 2.1 < script >元素 元素描述async立即开始下载脚本&#xff0c;但不能阻止其他页面动作&#…

深圳智能制造半导体芯片行业源代码防泄密完整解决方案

一、芯片半导体行业防泄密&#xff0c;不能用监控及管控方式来实现&#xff0c;采用管控方式&#xff0c;首先不能主动防御&#xff0c;只能进行事后查询&#xff0c;并且管控方式&#xff0c;不利于嵌入式开发&#xff0c;对于嵌入式开发&#xff0c;不管是采用沙箱隔离或u口禁…

linux查看服务器内核CUP版本相关命令

服务器参考 计算架构&#xff1a;x86-64产品系列&#xff1a;华为云耀云服务器操作系列&#xff1a;CentOS 7 执行uname -a查看服务器内核版本 Linux hecs-82210 3.10.0-1160.92.1.el7.x86_64 #1 SMP Tue Jun 20 11:48:01 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux执行hostn…

Vue动态缓存KeepAlive

vue中keep-alive组件主要有三个常用的props。 1&#xff0c;include存放的name是组件自身的name属性&#xff0c;只有名称匹配的组件会被缓存2&#xff0c;exclude&#xff0c;任何名称匹配的组件都不会被缓存3&#xff0c;max&#xff0c;最多可以缓存多少组件实例&#xff0…

delete误删基表(seg$)bbed恢复cluster table

有客户通过delete误删了sys.seg$表的数据&#xff0c;重启数据库&#xff0c;发现数据库不能正常启动。 删除命令&#xff1a;delete from sys.seg$ t where ts#2; 数据库启动报错 Errors in file /u01/app/diag/rdbms/orcl/orcl/trace/orcl_ora_48064.trc (incident325391)…

【蓝桥杯入门记录】动态数码管例程

目录 &#xff08;1&#xff09;例程1&#xff1a;两个数码管显示不同内容。本例以第一个数码管显示数字“0”&#xff0c;第二个数码管显示数字“1”为例。 &#xff08;2&#xff09;例程2&#xff1a;多个数码管显示不同内容&#xff08;二&#xff09;。注&#xff1a;创建…

HarmonyOS 开发之———应用程序入口—UIAbility的使用

谢谢关注!! 前言:上一篇文章主要介绍ArkJS 基础—〉自定义组件使用。如需了解谢谢查阅:http://t.csdnimg.cn/01PQ2 一、UIAbility概述 UIAbility是一种包含用户界面的应用组件,主要用于和用户进行交互。UIAbility也是系统调度的单元,为应用提供窗口在其中绘制界面。 …

掌握结构化日志记录:全面指南

在当今复杂的软件生态系统中&#xff0c;应用程序日志非常宝贵。它们允许开发者窥视应用程序的内部&#xff0c;了解系统内部的真实情况。但是&#xff0c;传统的非结构化日志数据有很多不足之处。这些混乱的文本块无法提供完整的画面。要真正发挥日志的力量&#xff0c;我们需…

浅析扩散模型与图像生成【应用篇】(三)——RDDM

3. Residual Denoising Diffusion Models 该文提出一种残差去噪扩散模型&#xff08;RDDM&#xff09;可用去图像生成和图像修复&#xff08;如去除阴影、去雨、暗光提升等&#xff09;。该文最大的特点是提出一种双扩散模型&#xff0c;在扩散过程中不仅包含噪声 ϵ \epsilon …

Windows WMI详解

WMI简介 WMI ( Windows Management Instrumentation, Windows管理规范)是Windows 2000/XP管理系统的核心&#xff0c;属于管理数据和操作的基础模块。设计WMI的初衷是达到一种通用性&#xff0c;通过WM操作系统、应用程序等来管理本地或者远程资源。它支持分布式组件对象模型(…

select * from 表 c=‘1‘ and b=‘2‘ and a=‘3‘; abc是联合索引,这样查询会命中索引吗?

倒叙也会命中索引 但是要注意&#xff0c;倒叙的时候必须要有a存在&#xff0c;否则就会索引失效 因为mysql底层会有优化器去进行优化&#xff0c;但是如果没有a的话&#xff0c;那么优化器就不知道要优化那个索引了&#xff0c;所以他走了全表&#xff0c;导致索引失效

[MYSQL数据库]--mysql的基础知识

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、数据库…