当前位置: 首页 > news >正文

SQLite 全面指南与常用操作

本文档为 SQLite 使用的详尽参考与实战指南,覆盖从基础概念、安装、命令行操作,到性能调优、并发与底层机制、备份恢复、扩展模块(FTS5/JSON1/R-Tree)、编程语言示例以及常见故障排查与实用脚本。适合开发者、运维与研究人员作为日常参考手册。

一. 快速开始(5 分钟上手)

1.1安装 SQLite CLI

  • Debian/Ubuntu: sudo apt install sqlite3

  • macOS: brew install sqlite

  • Windows: 下载 sqlite-tools,使用 sqlite3.exe

1.2创建数据库并执行简单命令

sqlite3 demo.db
sqlite> .headers on
sqlite> .mode column
sqlite> CREATE TABLE people(id INTEGER PRIMARY KEY, name TEXT, age INTEGER);
sqlite> INSERT INTO people (name, age) VALUES ('Alice', 30), ('Bob', 25);
sqlite> SELECT * FROM people;
sqlite> .exit

1.3 命令行工具使用(以 Windows 为例)

  1. 下载 SQLite 核心包:从 SQLite 官网 下载 sqlite-tools-win32-x86-xxxx.zip
  2. 解压后得到 sqlite3.exe,双击运行即可进入命令行交互模式;
  3. 核心命令行指令:
    .help:查看所有命令行帮助;
    .open <数据库名>:打开或创建数据库(如 .open test.db,若不存在则在当前目录创建 test.db 文件);
    .tables:查看当前数据库中所有表;
    .schema <表名>:查看指定表的创建语句;
    .exit 或 .quit:退出命令行模式。

二、数据库基础操作

SQLite 以单个文件存储整个数据库(如 test.db),操作数据库的核心是 “打开 / 创建数据库” 和 “管理数据库元信息”。

2.1 创建 / 打开数据库

  • 命令行方式:通过 .open 指令,如 .open student.db(若 student.db 不存在则自动创建);
  • SQL 语句方式:无需显式 “创建数据库”,连接时指定不存在的文件名即自动创建;
  • 注意:特殊数据库 :memory: 表示内存数据库,数据仅存于内存,程序退出后丢失,适合临时测试:
    .open :memory:  -- 打开内存数据库
    

2.2 查看数据库信息

  • 查看所有表:
    .tables -- 命令行指令
    SELECT name FROM sqlite_master WHERE type='table'; -- SQL 语句(通用)
  • 查看表结构:

    .schema student  -- 命令行指令,查看 student 表结构
    PRAGMA table_info(student);  -- SQL 语句,查看表字段详情(含类型、主键等)

三、表操作(DDL:数据定义语言)

表是 SQLite 存储数据的核心载体,DDL 操作包括创建表、修改表、删除表,需遵循 SQLite 数据类型规则(SQLite 采用 “动态类型”,字段类型仅为建议,实际存储按值的类型决定)。

3.1 支持的数据类型

SQLite 常用数据类型(非严格约束,仅为 “类型提示”):

  • INTEGER:整数(支持主键自增);
  • TEXT:字符串(UTF-8/UTF-16 编码);
  • REAL:浮点数(如 3.14、1.2e5);
  • BLOB:二进制数据(如图片、文件);
  • NUMERIC:数值类型(自动适配整数 / 浮点数 / 日期)。

3.2 创建表(CREATE TABLE)

基本语法

CREATE TABLE [IF NOT EXISTS] 表名 (字段1 类型 [约束1] [约束2],字段2 类型 [约束],...,[表级约束]
);

常用约束说明:

  • PRIMARY KEY:主键(唯一标识记录,默认非空),若为 INTEGER 类型,可加 AUTOINCREMENT 实现自增;
  • NOT NULL:字段值不可为空;
  • UNIQUE:字段值唯一(允许多个 NULL);
  • DEFAULT <值>:默认值(如 DEFAULT 0DEFAULT CURRENT_TIMESTAMP);
  • FOREIGN KEY (子表字段) REFERENCES 父表(父表主键):外键(维护表间关联,需开启外键支持)。

示例:创建学生表(含外键关联班级表)

1.先创建班级表(父表):

CREATE TABLE IF NOT EXISTS class (class_id INTEGER PRIMARY KEY AUTOINCREMENT,  -- 班级ID(自增主键)class_name TEXT NOT NULL UNIQUE,             -- 班级名称(唯一非空)create_time DEFAULT CURRENT_TIMESTAMP        -- 创建时间(默认当前时间)
);

2.创建学生表(子表,关联班级表):

-- 开启外键支持(SQLite 默认关闭)
PRAGMA foreign_keys = ON;CREATE TABLE IF NOT EXISTS student (id INTEGER PRIMARY KEY AUTOINCREMENT,        -- 学生ID(自增主键)name TEXT NOT NULL,                          -- 姓名(非空)age INTEGER CHECK (age > 0 AND age < 150),   -- 年龄(范围约束)gender TEXT DEFAULT '未知',                  -- 性别(默认“未知”)class_id INTEGER,                            -- 关联班级ID-- 外键约束:student.class_id 关联 class.class_idFOREIGN KEY (class_id) REFERENCES class(class_id)ON DELETE SET NULL  -- 若班级被删除,学生的 class_id 设为 NULLON UPDATE CASCADE   -- 若班级ID更新,学生的 class_id 同步更新
);

3.3 修改表(ALTER TABLE)

SQLite 对 ALTER TABLE 支持有限,仅支持以下操作:

1.重命名表

ALTER TABLE student RENAME TO new_student;

2.添加字段

-- 给 student 表添加“电话”字段(允许为空,默认 NULL)
ALTER TABLE student ADD COLUMN phone TEXT;

3.重命名字段(SQLite 3.25.0+ 支持):

ALTER TABLE student RENAME COLUMN phone TO tel;

若需删除字段、修改字段类型 / 约束,需通过 “创建临时表 → 迁移数据 → 删除原表 → 重命名临时表” 实现,示例:

-- 1. 创建临时表(含修改后的结构)
CREATE TABLE student_temp AS SELECT id, name, age, gender, class_id FROM student;
-- 2. 删除原表
DROP TABLE student;
-- 3. 重命名临时表为原表名
ALTER TABLE student_temp RENAME TO student;

3.4 删除表(DROP TABLE)

-- 若表存在则删除(避免报错)
DROP TABLE IF EXISTS student;

四、数据操作(DML:数据操纵语言)

DML 用于增、删、改、查表中数据,是日常开发最频繁的操作。

4.1 插入数据(INSERT)

基本语法:

-- 1. 指定字段插入(推荐,字段顺序可自定义)
INSERT INTO 表名 (字段1, 字段2, ...) VALUES (值1, 值2, ...);-- 2. 不指定字段(需按表字段顺序插入所有值)
INSERT INTO 表名 VALUES (值1, 值2, ...);-- 3. 批量插入
INSERT INTO 表名 (字段1, 字段2, ...) 
VALUES (值1-1, 值1-2, ...), (值2-1, 值2-2, ...), ...;

示例:

-- 1. 插入班级数据
INSERT INTO class (class_name) VALUES ('高一(1)班'), ('高一(2)班');-- 2. 插入学生数据(关联班级ID=1)
INSERT INTO student (name, age, gender, class_id) 
VALUES ('张三', 16, '男', 1), ('李四', 15, '女', 2);-- 3. 插入默认值(gender 用默认值“未知”)
INSERT INTO student (name, age, class_id) VALUES ('王五', 16, 1);

4.2 更新数据(UPDATE)

基本语法:

UPDATE 表名SET 字段1=新值1, 字段2=新值2, ...[WHERE 条件]  -- 若省略 WHERE,将更新表中所有记录(谨慎!)[LIMIT 数量];  -- 限制更新条数(避免误操作)

示例:

-- 1. 将“王五”的年龄改为17(指定 WHERE 条件,安全)
UPDATE student SET age = 17 WHERE name = '王五';-- 2. 将班级ID=1的学生性别改为“男”(批量更新,加 LIMIT 限制)
UPDATE student SET gender = '男' WHERE class_id = 1 LIMIT 10;

4.3 删除数据(DELETE)

基本语法:

DELETE FROM 表名[WHERE 条件]  -- 省略则删除所有数据(谨慎!)[LIMIT 数量];

示例:

-- 1. 删除姓名为“李四”的学生
DELETE FROM student WHERE name = '李四';-- 2. 删除班级ID=2且年龄<16的学生(加条件过滤)
DELETE FROM student WHERE class_id = 2 AND age < 16;-- 3. 清空表(保留表结构,比 DROP TABLE 更安全)
DELETE FROM student;

4.4 查询数据(SELECT)

SELECT 是 SQL 中最灵活的操作,支持过滤、排序、分组、关联等复杂逻辑,基本语法:

SELECT [DISTINCT] 字段1, 字段2, ...  -- DISTINCT 去重FROM 表名1[JOIN 表名2 ON 关联条件]  -- 表关联(INNER/LEFT/RIGHT JOIN)[WHERE 行过滤条件][GROUP BY 分组字段]       -- 按字段分组[HAVING 分组过滤条件]     -- 过滤分组结果(需配合 GROUP BY)[ORDER BY 排序字段 [ASC/DESC]]  -- 排序(ASC升序,DESC降序,默认ASC)[LIMIT 偏移量, 条数];     -- 分页(偏移量可选,如 LIMIT 10 取前10条,LIMIT 5,10 取第6-15条)

常用查询场景示例:

1.基础查询:查询学生表所有字段:

SELECT * FROM student;  -- * 表示所有字段(生产环境建议指定具体字段,避免冗余)

2.条件过滤:查询班级 ID=1 且年龄≥16 的学生姓名和年龄:

SELECT name, age FROM student WHERE class_id = 1 AND age >= 16;

3.去重查询:查询所有学生的性别(去重):

SELECT DISTINCT gender FROM student;

4.排序查询:查询高一 (1) 班学生,按年龄降序排列:

SELECT name, age FROM studentWHERE class_id = (SELECT class_id FROM class WHERE class_name = '高一(1)班')ORDER BY age DESC;

5.表关联查询:查询学生姓名及所属班级名称(INNER JOIN 取两表匹配数据):

SELECT s.name AS 学生姓名, c.class_name AS 班级名称FROM student s  -- s 是 student 表的别名INNER JOIN class c  -- c 是 class 表的别名ON s.class_id = c.class_id;  -- 关联条件:学生的班级ID=班级的ID

6.分组统计:按班级分组,统计每个班级的学生人数:

SELECT c.class_name AS 班级, COUNT(s.id) AS 学生人数FROM class cLEFT JOIN student s ON c.class_id = s.class_id  -- LEFT JOIN 保留无学生的班级GROUP BY c.class_id  -- 按班级ID分组(确保分组唯一)HAVING COUNT(s.id) >= 1;  -- 过滤出学生数≥1的班级

7.分页查询:查询学生表第 2 页数据(每页 2 条):

-- 偏移量 = (页码-1)*每页条数 = (2-1)*2 = 2,取 2 条SELECT * FROM student LIMIT 2, 2;

五、高级操作

5.1 索引(INDEX)

索引用于加速查询,尤其当表数据量大时(如万级以上),但会增加插入 / 更新 / 删除的开销(需维护索引)。

1. 创建索引

-- 基本语法:给 student 表的 name 字段创建索引
CREATE [UNIQUE] INDEX [IF NOT EXISTS] 索引名 ON 表名(字段1, 字段2, ...);-- 示例1:给学生姓名创建普通索引(加速按姓名查询)
CREATE INDEX idx_student_name ON student(name);-- 示例2:给班级ID+年龄创建联合索引(加速“按班级+年龄”的组合查询)
CREATE INDEX idx_student_class_age ON student(class_id, age);-- 示例3:给班级名称创建唯一索引(确保班级名称唯一,与表约束 UNIQUE 功能类似)
CREATE UNIQUE INDEX idx_class_name ON class(class_name);

2. 删除索引

DROP INDEX IF EXISTS idx_student_name;

3. 查看索引

-- 查看所有索引
SELECT name FROM sqlite_master WHERE type='index';-- 查看指定表的索引
PRAGMA index_list(student);

5.2 事务(TRANSACTION)

SQLite 支持事务,确保一组操作 “要么全部成功,要么全部失败”,避免数据不一致。事务具有 ACID 特性(原子性、一致性、隔离性、持久性)。

基本语法:

BEGIN TRANSACTION;  -- 开始事务(可简写为 BEGIN)-- 执行一系列 DML 操作(如 INSERT/UPDATE/DELETE)COMMIT;  -- 提交事务(所有操作生效)-- 或ROLLBACK;  -- 回滚事务(取消所有操作,恢复到事务开始前状态)

示例:转账场景(确保扣款和收款同时成功)

BEGIN;-- 1. A 账户扣款 100UPDATE account SET balance = balance - 100 WHERE user = 'A';-- 2. B 账户收款 100UPDATE account SET balance = balance + 100 WHERE user = 'B';-- 若两步均无错误,提交事务;若有错误(如 B 账户不存在),执行 ROLLBACKCOMMIT;-- ROLLBACK;

5.3 视图(VIEW)

视图是虚拟表,基于查询结果创建,不存储实际数据,仅保存查询逻辑,用于简化复杂查询、控制数据访问权限。

1. 创建视图

CREATE [OR REPLACE] VIEW 视图名 AS 查询语句;-- 示例:创建“学生班级视图”,简化关联查询CREATE OR REPLACE VIEW v_student_class ASSELECT s.id, s.name, s.age, c.class_nameFROM student sLEFT JOIN class c ON s.class_id = c.class_id;

2. 使用视图

-- 像查询普通表一样查询视图SELECT * FROM v_student_class WHERE class_name = '高一(1)班';

3. 删除视图

DROP VIEW IF EXISTS v_student_class;

5.4 触发器(TRIGGER)

触发器是自动执行的程序,当表发生特定操作(INSERT/UPDATE/DELETE)时,触发预设的 SQL 逻辑,用于数据校验、日志记录等场景。

基本语法:

CREATE [TRIGGER IF NOT EXISTS] 触发器名
[BEFORE/AFTER/INSTEAD OF] 操作类型(INSERT/UPDATE/DELETE)
ON 表名
[FOR EACH ROW]  -- 行级触发器(每操作一行触发一次)
BEGIN-- 触发执行的 SQL 逻辑
END;

示例:记录学生表的更新日志

1.先创建日志表:

CREATE TABLE student_log (log_id INTEGER PRIMARY KEY AUTOINCREMENT,student_id INTEGER,  -- 被操作的学生IDold_age INTEGER,     -- 更新前的年龄new_age INTEGER,     -- 更新后的年龄operate_time DEFAULT CURRENT_TIMESTAMP);

2.创建触发器:当学生表的年龄被更新时,自动插入日志:

CREATE TRIGGER trg_student_update_ageAFTER UPDATE ON student  -- 学生表更新后触发FOR EACH ROW             -- 每更新一行触发一次WHEN OLD.age != NEW.age  -- 仅当年龄发生变化时触发BEGININSERT INTO student_log (student_id, old_age, new_age)VALUES (OLD.id, OLD.age, NEW.age);  -- OLD 表示更新前的记录,NEW 表示更新后的记录END;

3.测试触发器:

-- 更新学生年龄,触发器会自动插入日志UPDATE student SET age = 18 WHERE name = '张三';-- 查看日志SELECT * FROM student_log;

4.删除触发器:

DROP TRIGGER IF EXISTS trg_student_update_age;

六、常用函数

SQLite 提供丰富的内置函数,简化数据处理:

函数类别函数名功能示例
字符串LENGTH(str)LENGTH(name):获取姓名长度
UPPER(str)UPPER(name):姓名转大写
数值COUNT(col)COUNT(id):统计非空记录数
SUM(col)SUM(age):计算年龄总和
AVG(col)AVG(age):计算平均年龄
日期DATE()DATE():获取当前日期(如 '2024-05-20')
DATETIME()DATETIME():获取当前日期时间
条件CASE WHENCASE WHEN age>=18 THEN '成年' ELSE '未成年' END

七、注意事项

  1. 外键支持:SQLite 默认关闭外键约束,需通过 PRAGMA foreign_keys = ON; 开启(每次连接需重新执行,或在工具中配置默认开启);
  2. 主键自增:仅 INTEGER 类型主键支持 AUTOINCREMENT,且需确保字段是主键;
  3. 数据类型灵活性:SQLite 是 “动态类型”,字段类型仅为建议,如 TEXT 字段可存储整数,但建议遵循字段类型设计,避免混乱;
  4. 性能优化
    • 大表查询需创建合适索引;
    • 批量操作(如批量插入)建议用事务包裹,减少磁盘 IO;
    • 避免使用 SELECT *,仅查询需要的字段;
  5. 备份与恢复:SQLite 数据库是单个文件,直接复制 .db 文件即可备份;恢复时替换原文件即可。
http://www.dtcms.com/a/350374.html

相关文章:

  • 没有AI背景的团队如何快速进行AI开发
  • expdp导出dmp到本地
  • docker 安装配置 redis
  • PDF处理控件Spire.PDF系列教程:在 C# 中实现 PDF 与字节数组的互转
  • 2025年06月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • synchronized关键字的底层原理
  • 蘑兔音乐:创作好搭子
  • 嵌入式C语言进阶:深入理解sizeof操作符的精妙用法
  • 隧道监测实训模型
  • 讲解 JavaScript 中的深拷贝和浅拷贝
  • PyPI 是什么?
  • CCleaner中文版:强大的系统优化与隐私保护工具,支持清理磁盘、注册表和卸载软件
  • `mysql_query()` 数据库查询函数
  • Ubuntu 22.04 中安装 ROS2 Humble
  • Java AI插件“飞算“实战测试:一键生成医院药品管理系统
  • Maven下载历史版本
  • 大模型微调 Prompt Tuning与P-Tuning 的区别?
  • 【44页PPT】DeepSeek在银行业务场景的应用(附下载方式)
  • AI 应用开发:从 Prompt 工程到实战应用开发
  • 基于RD算法的多目标SAR成像原理及MATLAB实现
  • 离线开发平台-HTTP数据同步到Doris数仓能力演示
  • GNN:用MPNN(消息传递神经网络)落地最短路径问题模型训练全流程
  • VS2010 在查找预编译头使用时跳过
  • 微服务商城构筑其一
  • [系统架构设计师]知识产权(二十)
  • 深度学习篇---混淆矩阵
  • 工业物联网如何提高生产效率
  • IsaacLab的关键函数位置
  • crc16是什么算法
  • LeetCode算法日记 - Day 21: 消失的两个数字、替换所有的问号