【Qt】三种操作sqlite3的方式及其三种多表连接

一、sqlite3与MySQL数据库区别:

1. 数据库类型

  • SQLite3:是嵌入式数据库,它将整个数据库存储在单个文件中,不需要独立的服务器进程。这意味着它可以很方便地集成到各种应用程序中,如移动应用、桌面应用等。
  • MySQL:是客户端 - 服务器型数据库,需要一个独立的服务器进程来管理数据库。客户端通过网络连接到服务器进行数据操作,适合多用户、多客户端并发访问的场景。

2. 数据处理规模

  • SQLite3:由于其单文件存储和轻量级的特点,适合处理小型到中型的数据量。一般来说,它更适用于本地数据存储和简单的数据处理任务,如小型应用程序的配置数据存储、嵌入式设备的数据管理等。
  • MySQL:能够处理大规模的数据和高并发的访问。它具有强大的性能和扩展性,可以支持企业级应用和大型网站的数据存储和管理需求。

3. 并发性能

  • SQLite3:对并发写入的支持有限。同一时间只允许一个进程对数据库文件进行写操作,多个进程的写操作会被串行化,可能会导致性能瓶颈。不过,它对并发读取的支持较好。
  • MySQL:具备良好的并发性能,支持多个客户端同时进行读写操作。通过事务、锁机制等技术,MySQL 可以有效地处理高并发场景下的数据一致性和完整性问题。

4. 功能特性

  • SQLite3:功能相对简单,提供了基本的 SQL 支持,包括数据定义、数据操作和数据查询等功能。但它缺少一些高级特性,如存储过程、触发器等。
  • MySQL:功能丰富,支持存储过程、触发器、视图、事务处理、外键约束等高级特性。这些特性可以帮助开发人员实现更复杂的业务逻辑和数据处理需求。

5. 安全性

  • SQLite3:安全性相对较低,因为它没有内置的用户认证和授权机制。数据库文件的访问权限主要依赖于操作系统的文件权限设置。
  • MySQL:提供了较为完善的用户认证和授权机制,可以对不同用户授予不同的数据库操作权限,从而保证数据的安全性。

二、连接多个表三种方式

总结:

  • 等值连接和内连接:只返回两个表中匹配的行,不包含任何表中的不匹配行。
  • 左外连接:返回左表的所有行,以及右表中匹配的行,右表不匹配的行用 NULL 填充。
  • 右外连接:返回右表的所有行,以及左表中匹配的行,左表不匹配的行用 NULL 填充。
  • 全外连接:返回左右两个表的所有行,不匹配的行用 NULL 填充。

1. 等值连接

等值连接是一种基本的连接方式,它通过在连接条件中使用等号(=)来匹配两个表中指定列的值。通常情况下,等值连接用于关联两个表的主键和外键,以确保数据的一致性。

特点

  • 只返回两个表中匹配的行,即只有当 Orders.CustomerID 和 Customers.CustomerID 的值相等时,才会将相应的行组合在一起。
  • 通常使用 WHERE 子句来指定连接条件。

-- 1.等值连接,主键与外键关联
SELECT *
FROM video as a,sq_channel as b,video_type as c
WHERE a.channel_id=b.channel_id
AND a.videoType_id=c.videoType_id

2. 内连接(JOIN ON

内连接是一种更标准的连接方式,它使用 JOIN 关键字和 ON 子句来指定连接条件。内连接和等值连接的功能类似,都是只返回两个表中匹配的行。

特点

  • 语法更加清晰,将连接条件和查询条件分开,提高了代码的可读性。
  • 是现代 SQL 中推荐使用的连接方式。

-- 2.内连接join on
SELECT *
FROM video
JOIN sq_channel
ON video.channel_id=sq_channel.channel_id
JOIN video_type
ON video.videoType_id=video_type.videoType_id

3. 外连接

注意:sqlite3无法右外连接与全外连接

外连接会返回一个表中的所有行,以及另一个表中匹配的行。如果另一个表中没有匹配的行,则用 NULL 填充。外连接分为左外连接、右外连接和全外连接。

(1)左外连接(LEFT JOIN 或 LEFT OUTER JOIN

左外连接以左表为主,返回左表中的所有行,以及右表中匹配的行。如果右表中没有匹配的行,则用 NULL 填充。

-- (1)左外连接,以左表为主全部显示,右表根据条件去匹配
SELECT *
FROM video
LEFT JOIN sq_channel
on video.channel_id=sq_channel.channel_id;

(2)右外连接(RIGHT JOIN 或 RIGHT OUTER JOIN

右外连接以右表为主,返回右表中的所有行,以及左表中匹配的行。如果左表中没有匹配的行,则用 NULL 填充。

(3)全外连接(FULL JOIN 或 FULL OUTER JOIN

全外连接会返回左右两个表中的所有行,无论是否有匹配的行。如果某一行在另一个表中没有匹配的行,则用 NULL 填充。

三、三种操作 SQLite 数据库方式

总结:

  • 若需要多次执行相同结构的 SQL 语句,并且对安全性和性能有较高要求,建议使用 SQL 预处理。
  • 对于一次性执行的简单 SQL 语句,可选择 sqlite3_exec,它能让代码更简洁。
  • 对于简单的查询操作,且希望方便地处理查询结果,SQLite3_get_table 是个不错的选择,但要注意内存管理问题。

方案一:SQL 预处理

通常用在DML(数据操作语言)

SQL 预处理是指先准备好 SQL 语句,之后再绑定参数并执行。在 SQLite 里,主要借助 sqlite3_preparesqlite3_bind_* 和 sqlite3_step 等函数来实现。

  • 安全性高:能够有效防止 SQL 注入攻击。由于参数是通过绑定的方式传入,而非直接拼接进 SQL 语句,所以可避免恶意用户通过构造特殊输入来篡改 SQL 语句。
  • 不适合一次性执行的简单 SQL 语句:若只执行一次 SQL 语句,使用预处理会引入额外的开销,还不如直接执行简单。

void demo3(sqlite3* psqlite3)

{

    int res;

    sqlite3_stmt *pstmt;

    char user_name[20]="张三";

    char video_name[20]="熊出没";

    char sql[500]="SELECT record.record_id,record.user_id,record.video_id,record.time,record.data,sq_user.user_name,video.video_name\

            FROM record\

            JOIN sq_user on sq_user.user_id=record.user_id\

            JOIN video ON video.video_id=record.video_id\

            WHERE sq_user.user_name=? AND video.video_name=?;";

    res=sqlite3_prepare(psqlite3,sql,strlen(sql),&pstmt,NULL);

    if(res==SQLITE_OK)

    {

        sqlite3_bind_text(pstmt,1,user_name,strlen(user_name),NULL);

        sqlite3_bind_text(pstmt,2,video_name,strlen(video_name),NULL);

        while (sqlite3_step(pstmt)==SQLITE_ROW)

        {

             qDebug()<<"---------------------------";

             qDebug()<<"record_id="<<sqlite3_column_int(pstmt,0);

             qDebug()<<"user_id="<<sqlite3_column_int(pstmt,1);

             qDebug()<<"video_id="<<sqlite3_column_int(pstmt,2);

             qDebug()<<"time="<<sqlite3_column_int(pstmt,3);

             qDebug()<<"data="<<(char *)sqlite3_column_text(pstmt,4);

             qDebug()<<"user_name="<<(char *)sqlite3_column_text(pstmt,5);

             qDebug()<<"video_name="<<(char *)sqlite3_column_text(pstmt,6);

        }

    }

    else

    {

        qDebug()<<"操作数据错误码:"<<sqlite3_errcode(psqlite3);

        qDebug()<<"连接数据库失败的错误信息"<<sqlite3_errmsg(psqlite3);

    }

}

方案二:通用数据库处理 sqlite3_exec

sqlite3_exec 是 SQLite 提供的一个便捷函数,可用于执行单条或多条 SQL 语句。

  • 适用于简单场景:对于一次性执行的简单 SQL 语句,如创建表、插入少量数据等,使用 sqlite3_exec 非常方便。
  • 安全性差:直接将 SQL 语句作为字符串传入,容易遭受 SQL 注入攻击。若 SQL 语句包含用户输入,必须进行严格的输入验证和转义处理。
  • 结果处理不够灵活:只能通过回调函数来处理查询结果,对于复杂的结果处理逻辑,回调函数的使用可能会使代码变得复杂。

 *优势:可以用在DDL、DML

 * 注意:sqlite3_exec操作的是查询语句需要回调函数,其他语句不需回调函数,可直接写nullptr

*/

//回调函数针对查询结果集返回的列数取值

int mycallback(void* pdata,int col,char** value,char** colname)

{

    qDebug()<<"查询结果列数:"<<col;

    for(int i=0;i<col;i++)

    {

        qDebug()<<"colname["<<i<<"]"<<colname[i]<<"="<<value[i];

    }

    return 0;

}

void demo2(sqlite3* psqlite3)

{

    int res=0;

    char* errmsg;

    char sql[100]={0};

    char username[10]="张三";

    sprintf(sql,"select * from sq_user where user_name='%s';",username);

    qDebug()<<"sql="<<sql;

    //第三个回调函数只有在查询语句写,如果不查询直接写nullptr

    res=sqlite3_exec(psqlite3,sql,mycallback,nullptr,&errmsg);

    if(res==SQLITE_OK)

    {

        qDebug()<<"sqlite3_exec success";

    }

    else

    {

        qDebug()<<"操作失败的错误码:"<<sqlite3_errcode(psqlite3);

    }

}

方案三:常用操作 SQLite3_get_table

SQLite3_get_table 是一个用于执行 SQL 查询语句并将结果存储在二维数组中的函数。

结果处理方便:将查询结果存储在一个二维数组中,方便进行遍历和处理,无需使用回调函数

功能有限:主要用于查询操作,对于更新、插入、删除等操作,使用起来不如 sqlite3_exec 方便。

  • 适用于简单查询:对于简单的查询操作,能够快速获取结果,代码实现相对简单。
  • 功能有限:主要用于查询操作,对于更新、插入、删除等操作,使用起来不如 sqlite3_exec 方便。

 //优势:可以直接获取查询结果字段、数据、行数、列数,也是最常用数据库操作方式

void demo3(sqlite3* psqlite3)

{

    int res=0;

    char *errmsg;//接收错误信息

    char** datares;//接收查询结果集

    int row;

    int col;

    char sql[100]={0};

    char username[10]="张三";

    //sprintf(sql,"select * from sq_user where user_name='%s';",username);

    sprintf(sql,"select * from sq_user");

    qDebug()<<"sql="<<sql;

    res=sqlite3_get_table(psqlite3,sql,&datares,&row,&col,&errmsg);

    qDebug()<<"查询结果 row="<<row;

    qDebug()<<"查询结果 col="<<col;

    //取表头

    for(int i=0;i<col;i++)

    {

        qDebug()<<datares[i];

    }

    //取表数据

    for(int j=col;j<(row+1)*col;j++)

    {

        qDebug()<<datares[j];

    }

    qDebug()<<datares[0]<<"-"<<datares[1]<<"-"<<datares[2]<<"-"<<datares[3];

    qDebug()<<datares[4]<<"-"<<datares[5]<<"-"<<datares[6]<<"-"<<datares[7];

    qDebug()<<datares[8]<<"-"<<datares[9]<<"-"<<datares[10]<<"-"<<datares[11];

    qDebug()<<datares[12]<<"-"<<datares[13]<<"-"<<datares[14]<<"-"<<datares[15];

}

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

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

相关文章

mysqlworkbench导入.sql文件

1、MySQL Workbench 新建数据库 或者 在左侧导航栏的 ​Schemas 区域右键选择 ​Create Schema...输入数据库名称&#xff08;例如 mydatabase&#xff09;&#xff0c;点击 ​Apply确认创建&#xff0c;点击 ​Finish 2、选择目标数据库 在左侧导航栏的 ​Schemas 列表中&a…

《Spring Cloud Eureka 高可用集群实战:从零构建高可靠性的微服务注册中心》

从零构建高可用 Eureka 集群 | Spring Cloud 微服务架构深度实践指南 本文核心内容基于《Spring Cloud 微服务架构开发》第1版整理&#xff0c;结合生产级实践经验优化 实验环境&#xff1a;IntelliJ IDEA 2024 | JDK 1.8| Spring Boot 2.1.7.RELEASE | Spring Cloud Greenwich…

实变函数:集合与子集合一例(20250329)

题目 设 r , s , t r, s, t r,s,t 是三个互不相同的数&#xff0c;且 A { r , s , t } A \{r, s, t\} A{r,s,t}, B { r 2 , s 2 , t 2 } B \{r^2, s^2, t^2\} B{r2,s2,t2}, C { r s , s t , r t } C \{rs, st, rt\} C{rs,st,rt} 若 A B C A B C ABC 则 { r , s…

Redis设计与实现-哨兵

哨兵模式 1、启动并初始化sentinel1.1 初始化服务器1.2 使用Sentinel代码1.3 初始化sentinel状态1.4 初始化sentinel状态的master属性1.5 创建连向主服务器的网络连接 2、获取主服务器信息3、获取从服务器的信息4、向主从服务器发送信息5、接受主从服务器的频道信息6、检测主观…

蓝桥杯省模拟赛 字符串拼接

问题描述 给定四个字符串 a,b,c,d&#xff0c;请将这四个字符串按照任意顺序依次连接拼成一个字符串。 请问拼成的字符串字典序最小是多少&#xff1f; 输入格式 输入四行&#xff0c;每行包含一个字符串。 输出格式 输出一行包含一个字符串&#xff0c;表示答案。 样例…

【大前端系列20】JavaScript核心:项目实战从零构建任务管理系统

JavaScript核心&#xff1a;项目实战从零构建任务管理系统 系列: 「全栈进化&#xff1a;大前端开发完全指南」系列第20篇 核心: 将JavaScript异步编程、事件循环等核心知识应用于实际项目开发 &#x1f4cc; 引言 在前面的文章中&#xff0c;我们深入探讨了JavaScript中的异步…

STM32单片机的桌面宠物机器人(基于HAL库)

效果 基于STM32单片机的桌面宠物机器人 概要 语音模块&#xff1a;ASR PRO&#xff0c;通过天问block软件烧录语音指令 主控芯片&#xff1a;STM32F103C8T6 使用HAL库 屏幕&#xff1a;0.96寸OLED屏&#xff0c;用来显示表情 4个舵机&#xff0c;用来当作四只腿 底部一个面…

计算机视觉初步(环境搭建)

1.anaconda 建议安装在D盘&#xff0c;官网正常安装即可&#xff0c;一般可以安装windows版本 安装成功后&#xff0c;可以在电脑应用里找到&#xff1a; 2.创建虚拟环境 打开anaconda prompt&#xff0c; 可以用conda env list 查看现有的环境&#xff0c;一般打开默认bas…

SQL Server数据库引擎服务启动失败:端口冲突

问题现象&#xff1a; SQL Server 2022 安装完成后&#xff0c;数据库引擎服务无法启动&#xff0c;日志报错 “TCP 端口 1433 已被占用”&#xff08;ERROR_LOG_SYS_TCP_PORT&#xff09;。 快速诊断 检测端口占用&#xff1a; # 查看 1433 端口占用情况&#xff08;需管理员权…

全局思维与系统思考

最近接到一些需求&#xff0c;1号位希望每个层级的领导者有眼界&#xff0c;胸怀&#xff0c;格局&#xff0c;全局观&#xff0c;这些听起来似乎很抽象&#xff0c;然而它们是每个人、每个团队成长与成功的核心竞争力。那么&#xff0c;如何才能提升这些能力&#xff1f;就像我…

区间有关的贪心解题记录435无重叠区间452用最少数量的箭引爆气球

无重叠区间我的想法是开一个数组a&#xff0c;遍历给出的区间&#xff0c;在数组a里将对应落在的区间index标记。如果有重复区间就只选择最小的那个区间标记。但是这道题的区间好像很长-5 * 104 < starti < endi < 5 * 104没法用数组a表示总的区间范围。 核心思路是当…

天锐蓝盾终端安全防护——企业终端设备安全管控

从办公室的台式电脑到员工手中的移动终端&#xff0c;这些设备不仅是工作的得力助手&#xff0c;更是企业数据的重要载体。然而&#xff0c;随着终端设备的广泛使用&#xff0c;安全风险也如影随形。硬件设备使用不当、数据随意传输等问题频发&#xff0c;使得企业数据面临着泄…

k8s网络策略

k8s网络策略 k8s网络测试概述查看防火墙策略 k8s网络策略网络访问控制案例&#xff1a;配置k8s网络策略结果验证 k8s网络策略配置示例 k8s网络测试概述 网络策略就是设置防火墙 查看防火墙策略 # 获取当前命名空间下的所有 NetworkPolicy 资源&#xff08;网络策略&#xff0…

leetcode刷题日记——跳跃游戏 II

[ 题目描述 ]&#xff1a; [ 思路 ]&#xff1a; 题目要求在一个一定能达到数组末尾的跳跃数组中(见55题 跳跃游戏)&#xff0c;找出能够跳到末尾的最小次数要求次数最少&#xff0c;那肯定是选取能选步数中最大的数。也就是在当前能够达到的距离中&#xff0c;选择能够达到的…

【Java SE】Java比较器:Comparable、Comparator

目录 1.前言 2.Comaprable接口 2.1 使用细节 2.2 案例演示 3.Comparator接口 3.1 为什么需要Comparator接口 3.2 使用细节 3.3 案例演示 4.Comparable、Comparator对比 1.前言 Java 中的对象&#xff0c;正常情况下&#xff0c;只能进行比较&#xff1a; 或 ! 。不…

(二)创建实例

在这节中&#xff0c; 创建一个实例初始化Vulkan库,指定驱动程序需要使用的应用程序信息 1&#xff0c;要有个实例句柄 VkInstance instance; 2&#xff0c;设置创建Vulkan驱动程序需要的信息&#xff0c; VkInstanceCreateInfo createInfo {}; createInfo.sType VK_STRUCTUR…

HCIP之VRRP

1. VRRP是什么 VRRP&#xff08;Virtual Router Redundancy Protocol&#xff0c;虚拟路由冗余协议&#xff09;是一种用于提高网络可靠性的容错协议。它通过将多台路由器虚拟成一台虚拟路由器&#xff0c;实现网关的冗余备份。当主路由器&#xff08;Master&#xff09;出现故…

高效内存管理:x86-64架构中的分页机制

在 x86-64 架构的世界里&#xff0c;内存分页机制扮演着举足轻重的角色&#xff0c;它就像是一座桥梁&#xff0c;连接着虚拟地址与物理地址。简单来说&#xff0c;内存分页机制就是将线性地址&#xff08;也就是虚拟地址&#xff09;切分成一个个固定大小的页&#xff0c;并把…

【软件工程】填空题

真题 2024-10 16.数据字典是用来定义_____中各个成分的具体含义的。 17.模块设计的基本原则是_____。 18.接口是操作的一个集合,其中每个操作描述了类、构件或子系统的一个_____。 19.耦合是指不同模块之间_____的度量。 20.RUP的突出特点是,它是一种以用况为驱动的、…

第二卷:海盐城血战(37-72回)正反人物群像

第二卷&#xff1a;海盐城血战&#xff08;37-72回&#xff09;正反人物群像 核心矛盾&#xff1a;寒门军事崛起 → 内部倾轧 → 制度性腐败 主题&#xff1a;通过人物群像展现寒门胜利的虚幻性与权力异化的必然性 一、正派阵营&#xff08;寒门抗争势力&#xff09; 1. 刘裕…