【网络编程 + 数据库】select 与 epoll 核心区别详解 + SQLite 入门到 C 接口全攻略

本篇为当日学习整理笔记,系统梳理IO 多路复用中 select 与 epoll 的核心差异 ,以及SQLite 轻量数据库的基础语法、常用命令与 C 语言接口。内容从基础概念到实操语法,再到编程接口,适合嵌入式 / 网络编程入门学习者复习参考。

文章目录

  • [一、IO 多路复用:select 与 epoll 核心区别](#一、IO 多路复用:select 与 epoll 核心区别)
    • [1.1 核心区别总览表](#1.1 核心区别总览表)
    • [1.2 select 核心特点](#1.2 select 核心特点)
    • [1.3 epoll 核心特点](#1.3 epoll 核心特点)
  • [二、SQLite 数据库基础](#二、SQLite 数据库基础)
    • [2.1 数据库的概念与分类](#2.1 数据库的概念与分类)
    • [2.2 SQLite 安装](#2.2 SQLite 安装)
    • [2.3 SQLite 常用元命令](#2.3 SQLite 常用元命令)
  • [三、SQL 基础语法全梳理](#三、SQL 基础语法全梳理)
    • [3.1 SQLite 支持的数据类型](#3.1 SQLite 支持的数据类型)
    • [3.2 表的创建与删除](#3.2 表的创建与删除)
    • [3.3 数据操作:增删改查](#3.3 数据操作:增删改查)
    • [3.4 条件查询与排序](#3.4 条件查询与排序)
    • [3.5 多表联合查询](#3.5 多表联合查询)
  • [四、SQLite C 语言接口详解](#四、SQLite C 语言接口详解)
    • [4.1 sqlite3_open:打开数据库](#4.1 sqlite3_open:打开数据库)
    • [4.2 sqlite3_exec:执行 SQL 语句](#4.2 sqlite3_exec:执行 SQL 语句)
    • [4.3 sqlite3_close:关闭数据库](#4.3 sqlite3_close:关闭数据库)
  • 五、学习总结

一、IO 多路复用:select 与 epoll 核心区别

IO 多路复用是网络编程中处理高并发连接的核心技术,select 和 epoll 是 Linux 下最经典的两种实现,二者在设计思路、性能、触发模式上有本质区别。

1.1 核心区别总览表

对比维度 select epoll
监听集合本质 数组结构,有数量上限(默认 1024) 内核事件表,无数量上限
数据拷贝开销 每次调用都需在用户态与内核态间全量拷贝集合,开销大 事件表常驻内核,仅返回就绪事件,无需全量拷贝,开销小
触发模式 仅支持水平触发(低速模式) 支持水平触发(默认)和边沿触发(高速模式)
事件定位方式 需手动遍历整个集合查找就绪文件描述符 自动返回就绪 fd 列表,无需遍历

1.2 select 核心特点

  1. 文件描述符集合有上限 select 本质上通过fd_set数组管理待监听的文件描述符,受系统常量FD_SETSIZE限制,Linux 默认最大监听 1024 个文件描述符,不适合超大并发场景。
  2. 用户态与内核态拷贝开销大 select 的监听集合维护在应用层(用户态),每次调用都需要把整个集合从用户态拷贝到内核态,内核检测完事件后再拷贝回用户态。连接数越多,拷贝开销呈线性增长。
  3. 仅支持水平触发模式 水平触发也叫低速模式:只要文件描述符上还有未处理的数据,每次调用 select 都会重复通知该事件。优点是编程简单、不易丢数据,缺点是触发效率低。
  4. 需要手动遍历查找就绪 fd select 返回后只会告知 "有事件就绪",不会指明具体是哪个 fd,应用程序需要遍历整个监听集合逐个检查,连接数越多效率越低。

1.3 epoll 核心特点

  1. 监听事件无数量上限 epoll 在内核中通过红黑树管理待监听的文件描述符,没有数量上限,理论上只受限于系统内存,适合高并发大连接场景。
  2. 内核级管理,拷贝开销极低 epoll 的事件表直接常驻内核空间,应用程序仅在添加 / 删除 fd 时做一次拷贝,监听过程中无需重复拷贝整个集合。内核检测到就绪事件后,通过就绪链表直接返回事件,极大降低了资源开销。
  3. 双触发模式可选
    • 水平触发(默认):和 select 逻辑一致,有未处理数据就持续通知,编程简单。
    • 边沿触发:仅在数据到来的瞬间通知一次,是高速模式。处理效率更高,但要求程序一次性读完缓冲区数据,编程复杂度更高,处理不当容易丢数据。
  4. 自动返回就绪 fd epoll 返回时直接将就绪的文件描述符列表返回给应用层,程序不需要遍历整个集合,直接处理就绪事件即可,连接数越多效率优势越明显。

二、SQLite 数据库基础

2.1 数据库的概念与分类

数据库是能够对大批量数据进行高效增、删、改、查管理的软件,按照数据存储方式主要分为两大类:

(1)关系型数据库
  • 数据以表格形式存储在磁盘文件中,支持标准 SQL 语言操作
  • 代表产品:Oracle、MySQL、SQLite
  • 特点:数据结构严谨、支持事务、适合持久化存储
(2)非关系型数据库
  • 多为内存数据库,数据存储在内存中,读写速度极快
  • 代表产品:Redis、各类 NoSQL 数据库
  • 特点:读写速度快、结构灵活、适合高并发缓存场景

2.2 SQLite 安装

SQLite 是一款轻量级嵌入式数据库,无需独立服务进程,以单个文件形式存在,Linux 下安装命令:

复制代码
sudo apt-get install sqlite3

2.3 SQLite 常用元命令

注意:这类.开头的命令是 sqlite3 终端工具的内置命令,不是标准 SQL 语句,不需要加分号。

命令 功能
.tables 查看当前数据库中所有表名
.databases 列出当前附加的数据库名称与文件路径
.headers on/off 开启 / 关闭查询结果的列名显示
.mode 模式 设置数据显示格式(如 column、list 等)
.schema 表名 查看指定表的建表语句
.width 数值 设置每列的显示宽度

三、SQL 基础语法全梳理

SQL 是操作关系型数据库的标准语言,SQLite 支持标准 SQL 的核心子集。

3.1 SQLite 支持的数据类型

类型 说明
INTEGER 整数类型
REAL 浮点数类型
TEXT 文本字符串类型
BLOB 二进制数据类型

3.2 表的创建与删除

(1)创建表

语法:

复制代码
create table 表名 (
    列名称1 数据类型1,
    列名称2 数据类型2,
    ...
);

示例:

复制代码
create table student (
    id integer,
    name text,
    sex text,
    age integer,
    score integer
);
(2)删除表

语法:

复制代码
drop table 表名称;

示例:

复制代码
drop table student;

3.3 数据操作:增删改查

(1)插入数据 insert

语法:

复制代码
-- 全列插入
insert into 表名 values (值1, 值2, ...);
-- 指定列插入
insert into 表名 (列1, 列2) values (值1, 值2);

示例:

复制代码
-- 全列插入
insert into student values (1, "张三", "男", 18, 90);
-- 允许部分字段为NULL
insert into student values (3, "王二", NULL, NULL, NULL);
-- 指定列插入
insert into student (id, name, sex) values (4, "赵五", "男");
(2)查询数据 select

语法:

复制代码
select 列名称1, 列名称2 from 表名;
-- 查询所有列
select * from 表名;

示例:

复制代码
select * from student;
select name,score from student;
(3)更新数据 update

语法:

复制代码
update 表名称 set 列名称 = 新值 where 匹配条件;

示例:

复制代码
update student set score=91 where name="赵五";
(4)删除数据 delete

语法:

复制代码
delete from 表名称 where 列名称 = 值;

示例:

复制代码
delete from student where name = "王二";

3.4 条件查询与排序

(1)where 条件子句

用于筛选符合条件的数据,常用运算符:

运算符 含义
= 等于
<> 不等于
> 大于
< 小于
>= 大于等于
<= 小于等于
BETWEEN ... AND ... 在某个范围内
LIKE 模糊匹配,%代表任意字符

示例:

复制代码
-- 模糊查询姓赵的学生
select name,score from student where name like "赵%";
-- 查询成绩大于等于90分的学生
select name from student where score >= 90;
-- 多条件组合
select name,score from student where name like "赵%" and score > 95;
(2)排序 order by

语法:

  • asc:升序(默认)
  • desc:降序

示例:

复制代码
-- 男生按成绩降序排列
select name,score from student where sex="男" order by score desc;

3.5 多表联合查询

(1)cross join 交叉连接

返回两张表的笛卡尔积,即所有行的组合。 示例:

复制代码
select 学生信息.姓名 as 姓名, 课程信息.名称 as 课程, 课程信息.学分 as 学分 
from 学生信息 cross join 课程信息;
(2)inner join 内连接

只返回两张表中匹配条件的行,是最常用的连接方式。 示例:

复制代码
-- 两表连接
select 学生信息.姓名 as 姓名, 成绩信息.成绩 as 成绩 
from 学生信息 inner join 成绩信息 
on 学生信息.ID = 成绩信息.学生ID;
-- 三表连接
select 学生信息.姓名 as 姓名, 课程信息.名称 as 课程, 成绩信息.成绩 as 成绩
from 学生信息 inner join 成绩信息 on 学生信息.ID = 成绩信息.学生ID
inner join 课程信息 on 成绩信息.课程ID = 课程信息.ID;
(3)left outer join 左外连接

以左表为准,右表没有匹配数据时返回 NULL。 示例:

复制代码
select 学生信息.姓名 as 姓名,成绩信息.成绩 as 成绩 
from 学生信息 left outer join 成绩信息 
on 学生信息.ID = 成绩信息.学生ID;

四、SQLite C 语言接口详解

SQLite 提供了一套 C 语言函数接口,可在代码中直接操作数据库,核心有 3 个函数。

4.1 sqlite3_open:打开数据库

函数原型

复制代码
int sqlite3_open(
    const char *filename,   /* 数据库文件名(UTF-8编码) */
    sqlite3 **ppDb          /* 输出参数:数据库句柄 */
);
  • 功能:打开一个数据库文件,如果文件不存在则自动创建。
  • 参数
    • filename:数据库文件路径
    • ppDb:二级指针,用来返回数据库句柄,后续所有操作都通过该句柄完成
  • 返回值 :成功返回SQLITE_OK,失败返回对应错误码。

4.2 sqlite3_exec:执行 SQL 语句

函数原型

复制代码
int sqlite3_exec(
    sqlite3*,                  /* 已打开的数据库句柄 */
    const char *sql,           /* 要执行的SQL语句 */
    int (*callback)(void*,int,char**,char**),  /* 回调函数 */
    void*,                     /* 传给回调函数的参数 */
    char **errmsg              /* 输出参数:错误信息 */
);
  • 功能:执行一条标准 SQL 语句,是最核心的执行接口。
  • 参数说明
    1. 已打开的数据库句柄
    2. sql:要执行的 SQL 字符串
    3. callback:回调函数,仅执行 select 查询时使用 。每查到一行数据就会调用一次该函数,用于处理查询结果;增、删、改操作不需要回调,传NULL即可。
    4. 传给回调函数的第一个参数,可用来在主函数和回调之间传递数据
    5. errmsg:二级指针,执行失败时会指向错误描述字符串,使用完需要调用sqlite3_free()释放
  • 返回值 :成功返回SQLITE_OK,失败返回错误码。

回调函数说明: 原型:int callback(void *arg, int colnum, char **pcontent, char **ptitle)

  • arg:主函数传入的自定义参数
  • colnum:查询结果的列数
  • pcontent:字符串数组,存储每一列的内容
  • ptitle:字符串数组,存储每一列的列名 返回值必须为 0,否则会中断查询。

4.3 sqlite3_close:关闭数据库

函数原型

复制代码
int sqlite3_close(sqlite3*);
  • 功能:关闭数据库连接,释放相关资源。
  • 注意:程序结束前必须调用该函数,否则可能造成资源泄漏和数据损坏。

五、学习总结

  1. select 与 epoll 的核心差异在于事件管理的位置、拷贝开销、触发模式和事件定位方式,epoll 在高并发场景下性能远优于 select。
  2. SQLite 是轻量嵌入式关系型数据库,支持标准 SQL 语法,通过单个文件存储数据,适合嵌入式和小型项目。
  3. SQL 语法核心围绕增删改查,条件筛选、排序、多表连接是查询的核心技能。
  4. SQLite 的 C 接口简洁易用,sqlite3_open/sqlite3_exec/sqlite3_close三个函数即可完成绝大多数数据库操作,查询操作通过回调函数获取结果。
相关推荐
TDengine (老段)1 小时前
TDengine 错误处理 — 错误码、异常传播、故障恢复
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
长脖鹿Johnny1 小时前
游戏输入系统框架设计(三):网络输入权威与可验证性
网络·游戏·游戏开发·架构设计·输入系统·网络同步
zbyyd1 小时前
Linux 系统编程 :select/epoll 多路复用与 SQLite 数据库实战
linux·数据库·sqlite
俊昭喜喜里1 小时前
c#中的构造函数
开发语言·数据库·c#
Mortalbreeze1 小时前
深入理解 Linux IO 模型(二):多路复用——select
linux·运维·服务器·网络·tcp/ip
养生技术人1 小时前
Oracle OCP认证考试题目详解082系列第17题
运维·数据库·sql·oracle·ocp
koi77u1 小时前
嵌入式学习———sqlite数据表
linux·数据库·学习·sqlite
SamChan901 小时前
PDF翻译服务端到端基准测试:4款主流方案的吞吐量、延迟、内存占用对比
服务器·网络·python·ai·pdf·wpf
Sagittarius_A*1 小时前
CVE-2026-42271:从 MCP stdio 测试接口看 LiteLLM 的命令执行风险与防御闭环
网络·windows·安全·cve·rce