当前位置: 代码网 > it编程>数据库>MsSqlserver > SQLite3基本介绍与常用语句汇总(最新整理)

SQLite3基本介绍与常用语句汇总(最新整理)

2025年06月16日 MsSqlserver 我要评论
sqlite3简介sqlite3是一款轻量级的、基于文件的开源关系型数据库引擎,由 d. richard hipp 于 2000 年首次发布。它遵循 sql 标准,但与传统的数据库系统不同,sqlit

sqlite3简介

sqlite3是一款轻量级的、基于文件的开源关系型数据库引擎,由 d. richard hipp 于 2000 年首次发布。它遵循 sql 标准,但与传统的数据库系统不同,sqlite 并不运行在独立的服务器进程中,而是作为一个嵌入式数据库引擎直接集成到应用程序中。其所有的数据结构(包括表、索引、事务日志等)都保存在一个单一的 .db 文件中。

sqlite 的设计理念是“零配置、开箱即用”,开发者只需将其动态库链接进应用程序,就可以直接进行数据库操作,无需安装数据库服务或进行网络配置。

sqlite3 是 sqlite 的第三个主要版本,相较前代有更强的兼容性和更完整的 sql 支持,是目前最常用的版本。

sqlite3的特点

  • 轻量嵌入式设计

sqlite3 不依赖服务器进程,仅作为应用的一部分存在;编译后的库小于 1mb,运行开销极低。

  • 单文件存储结构

所有数据库内容都保存在一个磁盘文件中,便于复制、迁移和版本控制。

  • 跨平台支持广泛

可以在 linux、windows、macos、android、ios 等操作系统中运行,源代码可编译到几乎所有主流平台。

  • 兼容标准 sql92

尽管体积小,但 sqlite3 支持大部分标准 sql 语法,如事务、子查询、视图、触发器、聚合函数等。

  • 零配置,无需安装

无需安装或初始化数据库,只要程序能访问数据库文件就可以使用。

  • 事务完整性(acid)支持

sqlite3 保证事务的原子性、一致性、隔离性和持久性,适用于数据完整性要求较高的应用。

sqlite3的适用场景 

sqlite3 由于其嵌入式、便携、小巧的特性,特别适用于以下场景:

  • 移动应用开发(android/ios)

sqlite3 是 android 系统默认数据库,适合存储用户数据、缓存内容、离线功能等。

  • 嵌入式系统 / iot 设备

如智能电视、车载系统、传感器节点等设备内存和性能有限,sqlite 是轻量数据存储的理想方案。

  • 桌面软件

常用于办公类软件(如记事本、财务管理工具)中提供本地数据存储功能。

  • 浏览器或前端环境

web 应用中的 indexeddb/localstorage 常借助 sqlite 作为底层数据库。

  • 单用户或低并发系统

适合使用场景为单人或单线程访问,例如个人记账软件、本地日志记录系统等。

  • 快速原型开发和测试

因为免安装、部署简单,sqlite 常被用于开发早期快速迭代和测试环境中。

  • 嵌套系统中的缓存数据库

可作为大型数据库系统的本地缓存,提升访问性能,降低服务器负载。

sqlite 命令行工具(sqlite3 shell) 中的内置命令

命令作用说明
.open filename.db打开或创建一个 sqlite 数据库文件
.tables列出当前数据库中的所有表
.schema [table]查看某个表或所有表的建表语句(ddl)
.headers on/off开启或关闭结果显示中的列标题
.read filename.sql执行指定的 sql 文件内容
.exit / .quit退出 sqlite 命令行
.databases查看当前连接的数据库文件
.nullvalue null_replacement设置 null 显示为什么字符串
.output filename.txt将查询结果输出到文件

基本操作语句

1.打开/创建数据库文件

sqlite 使用命令行或程序语言(如 python、c 等)调用 sqlite 引擎来打开或创建数据库文件。文件不存在时会自动创建。

sqlite3 mydatabase.db

该命令会在当前目录中创建一个名为 mydatabase.db 的数据库文件(如果尚不存在),并进入 sqlite 的交互式终端。你可以在里面执行 sql 命令。

2. 查看数据库中所有表

select name from sqlite_master where type='table';

或者使用 sqlite 命令行工具提供的快捷命令:

.tables

3. 查看表结构(pragma 语句)

pragma table_info(table_name);

示例:

pragma table_info(users);
cid | name  | type    | notnull | dflt_value | pk
----+-------+---------+---------+------------+----
0   | id    | integer | 0       | null       | 1
1   | name  | text    | 0       | null       | 0
2   | age   | integer | 0       | null       | 0

表相关操作

1. 创建表(create table

create table table_name (
    column1 datatype [constraints],
    column2 datatype [constraints],
    ...
);

用于定义一个新的数据表,并指定字段名、数据类型和约束(如主键、非空等)。

create table users (
    id integer primary key,
    name text not null,
    age integer
);

补充:查看某个表的建表语句. schema 表名

sqlite> .schema users
create table users (
    id integer primary key,
    name text not null,
    age integer
);

2. 修改表结构(alter table

sqlite 支持的 alter table 功能比较有限,主要包括:

#修改表名
alter table table_name rename to new_table_name;
#新增列
alter table table_name add column column_def;

示例:添加一个 email 字段

alter table users add column email text;
sqlite> .schema users
create table users (
    id integer primary key,
    name text not null,
    age integer,
    email text
);

你会发现 email 字段已经添加在表结构末尾。注意:sqlite 不支持删除列或修改列类型。

3. 删除表(drop table

drop table [if exists] table_name;
drop table if exists users;

4. 复制表结构与数据

sqlite 没有 create table ... like 语法,可以用以下方式复制结构和数据:

create table new_table as select * from old_table;

如果只想复制结构(不含数据):

create table new_table as select * from old_table where 0;

数据操作语句

1. 插入数据(insert into

insert into table_name (column1, column2, ...) values (value1, value2, ...);

也可以省略列名(前提是所有列都有值):

insert into table_name values (value1, value2, ...);

示例:

insert info uesrs (id, name, age, email) values (1, "alice", 25, "a@.com");
sqlite> select * from users;
id | name  | age | email
---+-------+-----+--------------------
1  | alice | 25  | a@.com

2. 更新数据(update

update table_name set column1 = value1, column2 = value2, ... where condition;

示例:

update users set age = 26 whrer id = 1;
sqlite> select * from users;
id | name  | age | email
---+-------+-----+--------------------
1  | alice | 26  | a@.com

3. 删除数据(delete

delete from table_name where condition;
注意:如果不加 where,会删除整张表的数据

示例:

sqlite> select * from users;
id | name  | age | email
---+-------+-----+--------------------
1  | alice | 26  | a@.com
delete from users where id = 1;
sqlite> select * from users;
-- 空表,无结果

4. 查询数据(select

select column1, column2, ... from table_name [where ...] [order by ...] [limit ...];

select * 表示查询所有列。

查询进阶

1. 条件筛选(where

select column1, column2 from table_name where condition;

常用操作符包括:=, !=, >, <, >=, <=, like, in, between, is null 等。

示例:

select * from users where age > 25;
id | name  | age | email
---+-------+-----+---------------------
2  | bob   | 30  | bob@example.com
3  | carol | 28  | carol@example.com

2. 排序(order by

select * from table_name order by column [asc|desc];

示例:

select * from users order by age desc;
id | name  | age | email
---+-------+-----+---------------------
2  | bob   | 30  | bob@example.com
3  | carol | 28  | carol@example.com
1  | alice | 25  | alice@example.com

3. 分组与过滤(group by + having

select group_column, aggregate_function(...) from table_name group by group_column [having condition];

示例:

select age, count(*) from users group by age having count(*) > 1;
假设有两名用户都 30 岁
age | count(*)
----+----------
30  | 2

4. 多表连接(join

select columns from table1
join table2 on table1.column = table2.column;

示例:

表users
id | name  | age | email
---+-------+-----+---------------------
2  | bob   | 30  | bob@example.com
3  | carol | 28  | carol@example.com
1  | alice | 25  | alice@example.com
表orders
user_id | amount
--------+--------
2       | 100
3       | 150
select users.name, orders.amount
from users
join orders on users.id = orders.user_id;
-- 输出:
name  | amount
------+--------
bob   | 100
carol | 150
 

5. 子查询与嵌套查询

select * from table where column in (select ... from ... where ...);

示例:

select name from users where id in (select user_id from orders where amount > 100);
输出:
name
-----
carol

6. 分页查询(limit / offset

select * from table_name limit 限制行数 offset 起始行偏移量;
指令说明
   limit:限制最多返回多少行结果。
   offset:跳过前面多少行数据再开始返回(可选)。

例如在一个页面中只显示 10 条数据,就可以:

select * from users order by id limit 10 offset 0;   -- 第1页
select * from users order by id limit 10 offset 10;  -- 第2页
select * from users order by id limit 10 offset 20;  -- 第3页

或者用更常见的公式:

limit 每页条数 offset (页码 - 1) * 每页条数

示例:

原始数据为:
id | name  | age
---+-------+-----
1  | alice | 25
2  | bob   | 30
3  | carol | 28
select * from users order by id limit 2 offset 1;
按 id 排序后,跳过第1条数据,从第2条开始取,最多取2条。
执行结果:
id | name  | age
---+-------+-----
2  | bob   | 30
3  | carol | 28

索引与性能

1.sqlite3中的索引是什么?

在 sqlite 中,索引是一种数据库对象,它的作用类似于书本的目录,可以加快查询特定数据的速度。索引会为一个或多个列生成一个排序的数据结构(通常是 b-tree),从而使查询更快。

2.索引的特性?

加速查询(尤其是 where、join、order by 等)

当你查询某张表时:

select * from users where age > 25;

如果 age 上有索引,sqlite 会用索引快速定位符合条件的数据,而不用全表扫描。

提升排序效率

select * from users order by name;

如果 name 列已建索引,排序可以直接利用索引顺序完成,而无需临时排序。

加速多表连接(join)

select * from users join orders on users.id = orders.user_id;

如果 orders.user_id 建了索引,那么连接时匹配效率会更高。

不适用于频繁变动的字段

索引虽然能加速查询,但会减慢 insertupdatedelete 的性能,因为每次数据改动,索引也要同步更新

3. 创建索引(create index

为单列创建索引

create [unique] index index_name on table_name(column_name);
unique 表示不允许重复值(可选)。

示例:

create index idx_users_age on users(age);
#查看是否命中索引
explain query plan select * from users where age > 25;
#输出
search table users using index idx_users_age (age>?)
说明查询使用了你创建的索引。

为多列创建联合索引

create index index_name on table_name(column1, column2, ...);

适用于查询中使用多个字段组合的情况。

遵守“最左前缀原则”

示例:

select * from users where name = 'alice' and age = 25;
#查看是否命中索引
explain query plan select * from users where name = 'alice' and age = 25;
#输出
search table users using index idx_users_name_age (name=? and age=?)

最左前缀原则: 复合索引只有在查询中使用了从左到右的“最前面的列”时,sqlite 才会使用该索引来优化查询。

示例:

id | name  | age
---+-------+-----
1  | alice | 25
2  | bob   | 30
3  | carol | 28
#创建复合索引
create index idx_name_age on users(name, age);

分别执行以下查询并查看是否命中索引

①使用 name(最左列),可以命中索引

explain query plan select * from users where name = 'alice';
search table users using index idx_name_age (name=?)

②使用 name + age(最左列 + 第二列),仍命中索引

explain query plan select * from users where name = 'alice' and age = 30;
search table users using index idx_name_age (name=? and age=?)

③只使用 age,不命中索引

explain query plan select * from users where age = 30;
scan table users

④使用 age + name(第二列 + 最左列),仍命中索引,顺序不影响

explain query plan select * from users where age = 30 and name = 'alice';
search table users using index idx_name_age (age=? and name=?)

注意:复合索引 idx_name_age(name, age) 是一棵按 name 排序、再按 age 排序的 b 树结构。查询必须从最左的列开始匹配,否则无法用上这个索引。

4. 删除索引(drop index

drop index [if exists] index_name;

事务控制

1. 开始事务(begin

begin;
  • 用于开始一个事务。在事务开始后,所有的操作(如 insertupdatedelete)都将在这个事务中进行。
  • 如果事务内的操作没有出现错误,事务可以被提交(commit)。如果出错,可以回滚(rollback)整个事务。

2. 提交事务(commit

commit;

提交当前事务所做的所有更改。这会将事务中所有修改的数据写入数据库并使它们永久生效。

示例:提交事务

begin;
insert into users (name, age, city) values ('eve', 40, 'chengdu');
update users set age = 45 where name = 'alice';
commit;

3. 回滚事务(rollback

rollback;

如果在事务中执行某些操作时发生错误,可以使用 rollback 来撤销所有在当前事务中的操作,恢复到事务开始前的状态。

示例:回滚事务

begin;
insert into users (name, age, city) values ('eve', 40, 'chengdu');
update users set age = 45 where name = 'alice';
-- 假设此时发生了错误,我们决定回滚事务
rollback;

事务回滚后,evealice 的更新都将被撤销,users 表中的数据保持不变。

4. 自动提交模式

  • 在默认情况下,sqlite 在每个独立的 sql 语句后自动提交。也就是说,每次执行一条语句时,sqlite 会自动把它作为一个单独的事务提交。
  • 为了防止自动提交,可以显式地使用 begin 开始事务,直到使用 commitrollback

5. 提交或回滚事务的应用场景

  • 批量操作: 比如一次性插入大量数据,使用事务能够保证所有数据同时插入成功,避免数据不一致。
  • 处理失败的操作: 在多步操作中,如果中途某一步失败,rollback 可以保证整个操作的原子性。

事务控制的典型应用场景:

假设有一个转账操作,其中两个表分别是 accounts(账户余额)和 transactions(交易记录),我们需要确保转账操作成功或者完全回滚。

try {
        executeorthrow(db, "begin;");
        executeorthrow(db, "update accounts set balance = balance - 100 where account_id = 'a001';");
        // 故意出错:列名 balxxx 不存在
        executeorthrow(db, "update accounts set balxxx = balance + 100 where account_id = 'a002';");
        executeorthrow(db, "insert into transactions (from_account, to_account, amount) values ('a001', 'a002', 100);");
        //没问题就提交
        executeorthrow(db, "commit;");
        std::cout << "transaction committed.\n";
    } catch (const std::exception& ex) {
        std::cerr << ex.what() << "\n";
        //出错回滚
        sqlite3_exec(db, "rollback;", nullptr, nullptr, nullptr);
        std::cout << "transaction rolled back.\n";
    }

视图与临时表

视图(view)

视图是 虚拟的表,本质上是对一个 select 查询结果的封装,它本身不存储数据,而是每次访问时执行背后的查询语句。它的存在意义主要在于以下几点:

1. 简化复杂查询

当你有一些经常要执行的复杂 join子查询聚合查询 时,把它们写进视图,可以像操作普通表一样简单调用:

-- 查询最近30天订单金额前10的用户
select * from top_users_last_30_days;

而不用每次都写长查询。

一个视图可以作为多个后续查询的中间层,避免重复 joingroup by 逻辑,提高可复用性和效率。

2. 增强可读性与可维护性

把复杂查询逻辑隐藏到视图中后,业务 sql 更清晰:

-- 直接查视图
select * from user_purchases_summary where total_spent > 1000;

而不是写重复的 sql 逻辑多处维护。

3.提高安全性

你可以只授予用户对视图的访问权限,而非对底层表的权限,从而达到权限隔离的效果。

创建视图:

create [temp | temporary] view view_name as
select ...;
view_name:视图名称
select ...:视图对应的查询语句
temp:可选,创建临时视图,仅在当前连接中可见

示例:创建一个只读用户信息视图

create view active_users as
select id, name, email
from users
where status = 'active';

你可以像查询普通表一样使用视图:

select * from active_users;
假设 users 表如下:
| id | name  | email                                   | status   |
| -- | ----- | --------------------------------------- | -------- |
| 1  | alice | [alice@mail.com](mailto:alice@mail.com) | active   |
| 2  | bob   | [bob@mail.com](mailto:bob@mail.com)     | inactive |
| 3  | carol | [carol@mail.com](mailto:carol@mail.com) | active   |
那么 active_users 视图返回:
| id | name  | email                                   |
| -- | ----- | --------------------------------------- |
| 1  | alice | [alice@mail.com](mailto:alice@mail.com) |
| 3  | carol | [carol@mail.com](mailto:carol@mail.com) |

 注意:如果你没有显式使用 temptemporary 关键字,那么你创建的视图就是持久视图

删除视图:

drop view active_users;

临时表(temp table)

临时表是只在当前数据库连接中可见的表,连接关闭后自动销毁。它们的主要目的是用于临时数据的存储与处理,不污染正式的数据表结构。它的存在意义主要在于以下几点:

1. 存放中间结果,简化复杂操作

在处理多步 sql 逻辑(如报表、分析、批量更新)时,临时表可以存放中间结果,让后续查询更清晰:

create temp table temp_summary as
select user_id, sum(amount) as total
from orders
group by user_id;

然后你可以继续基于 temp_summary 做筛选、排序等操作。

2. 提高性能,避免重复计算

有些数据在多个地方会用到,而计算代价较高(例如聚合、大量连接),你可以先写入临时表,然后反复查询:

-- 避免重复 join 操作,提高整体查询速度
select * from temp_result where score > 80;

3.并发安全,每个连接互不干扰

sqlite 的临时表是连接隔离的

  • 多个连接可以使用同名临时表
  • 它们之间的数据互不影响

这使得临时表非常适合多线程/多连接场景下的临时数据隔离处理

总结:临时表的作用是为当前连接提供一个安全、高效、隔离的临时数据空间,专注于中间处理、性能优化与调试而不影响正式数据库结构与数据。

创建临时表:

create temp table temp_table_name (
    column1 type,
    column2 type,
    ...
);
  • 临时表只在当前数据库连接中有效
  • 连接关闭后自动删除
  • 临时表与视图不同,它是真实存储数据的表,只是生命周期短

示例:创建并使用一个临时表

create temp table temp_orders (
    id integer,
    product text,
    quantity integer
);
insert into temp_orders values (1, 'book', 2);
insert into temp_orders values (2, 'pen', 5);
select * from temp_orders;
查询结果(临时表内容):
| id | product | quantity |
| -- | ------- | -------- |
| 1  | book    | 2        |
| 2  | pen     | 5        |

视图 vs 临时表

项目视图(view)临时表(temp table)
本质基于 select 的虚拟表,不存储数据存储真实数据的临时性表
是否持久存在是(除非使用 temp 创建)否,只在当前连接中存在,断开即销毁
数据存储不存储数据,每次使用实时查询底层表存储数据,像普通表一样支持增删改查
创建语法create [temp] view view_name as ...create temp table table_name (...)
删除方式drop view view_name;自动销毁(连接关闭)或手动 drop table
生命周期持久(数据库文件的一部分)连接会话级,连接断开即清除
可更新性只读(除非符合可更新视图条件)可读可写,完全等同于普通表
典型用途封装复杂查询、简化 sql、权限控制存储中间数据、性能优化、测试临时数据
是否支持索引否(依赖底层表索引)是(可为临时表单独建索引)
作用范围所有连接(持久视图)或当前连接(temp)当前连接
是否写入磁盘是(除 temp view否(仅存储在内存或临时磁盘空间)

常用函数与表达式

字符串处理函数

函数名功能说明示例 sql返回结果
length(x)返回字符串 x 的字符长度select length('sqlite');6
substr(x,y,z)提取 x 中从第 y 位开始的 z 个字符select substr('sqlite3', 2, 4);'qlit'
lower(x) / upper(x)转换为小写 / 大写select upper('abc');'abc'
trim(x)去除前后空白字符select trim(' abc ');'abc'
replace(x,y,z)x 中所有 y 替换为 zselect replace('hello', 'l', 'l');'hello'
instr(x, y)查找 yx 中首次出现的位置(1 开始)select instr('abcdef', 'cd');3
printf(fmt, ...)格式化字符串,类似 c 的 printfselect printf('%.2f', 3.14159);'3.14'
hex(x)将字符串或 blob 转为十六进制表示select hex('abc');'616263'

数值函数

函数名功能说明示例 sql返回结果
abs(x)绝对值select abs(-10);10
round(x[,y])四舍五入到 y 位小数,默认 0select round(3.14159, 2);3.14
random()返回一个大范围随机整数select random();随机整数
random() % n控制随机值范围(常配合 abs 使用)select abs(random() % 10);0 ~ 9
typeof(x)返回数据类型(如 integer, text)select typeof(3.14);'real'
coalesce(x, y, ...)返回第一个非 null 的值select coalesce(null, '', 'abc');''
nullif(x, y)如果 x == y,返回 null,否则返回 xselect nullif(5, 5);null
sign(x)不内置,可用 case 模拟,判断数正负select case when x > 0 then 1 when x < 0 then -1 else 0 end-1 / 0 / 1

日期与时间函数

函数名功能说明示例 sql返回结果
date('now')当前日期select date('now');2025-05-08
datetime('now')当前日期时间select datetime('now');2025-05-08 13:50:00
time('now')当前时间(不含日期)select time('now');13:50:00
strftime('%y-%m-%d', 'now')日期格式化输出select strftime('%y-%m-%d', 'now');2025-05-08
strftime('%s', 'now')当前时间戳(秒)select strftime('%s', 'now');unix 时间戳
strftime('%w', 'now')星期几(0 表示周日)select strftime('%w', 'now');4(周四)
julianday('now')当前日期的儒略日表示法(浮点)select julianday('now');2460451.08
datetime('now', '+7 days')时间加减(也支持 -2 hours, +1 month 等)select datetime('now', '-1 day');昨天的时间

聚合函数

函数名功能说明示例 sql返回结果
count(x)非 null 值数量select count(name) from users;42(示例)
count(*)所有行数量select count(*) from users;100
sum(x)求和select sum(price) from orders;2300.50
avg(x)平均值select avg(score) from exams;82.5
max(x)最大值select max(age) from people;64
min(x)最小值select min(age) from people;18

条件表达式

表达式功能说明示例 sql返回结果
case when ... then ...条件判断(if-else)select case when score > 90 then '优' when score > 60 then '中' else '差' end'优' / '中' / '差'
case x when a then ...值匹配(更紧凑形式)select case grade when 'a' then 4 when 'b' then 3 else 0 end4 / 3 / 0
coalesce(x, y, z)返回第一个非 null 值select coalesce(null, null, 'hello');'hello'
nullif(x, y)如果 x == y 则返回 null,否则返回 xselect nullif(5, 5);null
ifnull(x, y)如果 x 是 null,则返回 y,否则返回 x(别名)select ifnull(null, 'default');'default'

 示例:

下面是一个综合性 sql 示例,它模拟了一个电商订单分析的场景

建表:

-- 创建客户表
create table customers (
    id integer primary key,           -- 客户 id,主键
    name text,                        -- 客户名称
    email text                        -- 客户邮箱
);
-- 创建订单表
create table orders (
    id integer primary key,           -- 订单 id,主键
    customer_id integer,              -- 关联客户 id
    product_name text,                -- 商品名称
    price real,                       -- 商品单价
    quantity integer,                 -- 购买数量
    order_date text,                  -- 下单时间(格式:yyyy-mm-dd hh:mm:ss)
    foreign key (customer_id) references customers(id)  -- 外键关联客户表
);

插入数据: 

-- 插入客户
insert into customers (id, name, email) values
(1, 'alice', 'alice@example.com'),
(2, 'bob', 'bob@example.net'),
(3, 'charlie', 'charlie@example.org');
-- 插入订单
insert into orders (customer_id, product_name, price, quantity, order_date) values
(1, 'laptop', 899.99, 1, '2025-01-15 10:00:00'),
(1, 'mouse', 19.99, 2, '2025-02-10 12:30:00'),
(2, 'keyboard', 49.99, 1, '2025-03-05 14:20:00'),
(2, 'monitor', 199.99, 1, '2025-03-06 15:10:00'),
(2, 'usb cable', 9.99, 3, '2025-04-01 09:00:00'),
(3, 'desk chair', 129.99, 1, '2025-01-22 16:00:00');

 sql

select
    c.name as customer_name,  -- 客户名称
    upper(substr(c.email, 1, instr(c.email, '@') - 1)) as email_user,  
        -- 提取 email @ 前部分并转为大写
    count(o.id) as total_orders,  -- 订单总数
    sum(o.price * o.quantity) as total_spent,  -- 总消费金额
    round(avg(o.price * o.quantity), 2) as avg_order_value,  -- 平均订单金额(保留2位小数)
    max(o.order_date) as last_order_date,  -- 最后一笔订单的时间
    strftime('%y-%m', o.order_date) as order_month,  -- 订单月份(用于聚合)
    -- 消费金额区间分级:vip / gold / regular
    case 
        when sum(o.price * o.quantity) > 1000 then 'vip'
        when sum(o.price * o.quantity) > 500 then 'gold'
        else 'regular'
    end as customer_level
from
    customers c
left join
    orders o on c.id = o.customer_id  -- 关联订单表
where
    o.order_date >= date('now', '-6 months')  -- 仅查询最近6个月的订单
group by
    c.id
having
    total_orders > 0  -- 排除没有订单的客户
order by
    total_spent desc  -- 按总消费金额降序排列
limit 10;  -- 仅显示前10个客户

sqlite 专有特性

autoincrement 和 integer primary key

  • integer primary key 是 sqlite 中用于定义主键并且自动增长的特殊类型。
  • 如果你定义了某个列为 integer primary key,当向表中插入一行数据时sqlite 会自动为该列赋值(自增),无需显式使用 autoincrement
  • autoincrement 是一种“更严格”的版本,它会防止重复使用已删除的 id。
特性integer primary keyinteger primary key autoincrement
自动增长
会复用已删除的 id? 会不会
是否推荐? 推荐(性能更好)不推荐,除非必须保证唯一不复用

示例:

-- 普通自增主键
create table users (
    id integer primary key,
    name text
);
-- 带 autoincrement 的主键
create table logs (
    id integer primary key autoincrement,
    message text
);

without rowid 表

sqlite 默认使用一个隐藏的 rowid 来标识每一行。但你可以显式使用 without rowid 表来:

  • 减少存储开销(适合复合主键场景)
  • 提高某些查询性能(尤其当不需要 rowid 时)

示例:

-- 默认带有 rowid
create table cities (
    name text primary key,
    population integer
);
-- 不使用 rowid
create table cities_norowid (
    name text primary key,
    population integer
) without rowid;

说明without rowid 表要求必须有主键,且主键不可为 rowid

pragma 指令

pragma 是 sqlite 的一组特殊命令,用于查看或设置数据库的内部参数或行为。

指令用途说明示例
pragma table_info(table_name)查看表结构(字段信息)pragma table_info(users);
pragma foreign_keys查看外键是否启用(1 为开启)pragma foreign_keys;
pragma foreign_keys = on;启用外键约束pragma foreign_keys = on;
pragma database_list查看当前连接的数据库列表pragma database_list;
pragma index_list(table_name)查看表上的索引列表pragma index_list(users);
pragma cache_size设置或查看内存页缓存大小pragma cache_size = 2000;
pragma journal_mode设置事务日志模式(如 wal)pragma journal_mode = wal;
pragma synchronous控制同步级别(性能 vs 安全)pragma synchronous = normal;
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com