-- 基础语法
CREATE VIEW [IF NOT EXISTS] 视图名称 AS
SELECT 列1, 列2, ...
FROM 表名
[WHERE 条件]
[GROUP BY 分组]
[HAVING 过滤条件];
示例 1:简化多表关联查询
sql复制代码
-- 创建视图:客户订单视图
CREATE VIEW customer_orders AS
SELECT customers.name, orders.product, orders.order_date
FROM customers
JOIN orders ON customers.id = orders.customer_id;
示例 2:隐藏敏感字段
sql复制代码
-- 创建视图:公开员工信息(隐藏薪资)
CREATE VIEW employee_public AS
SELECT id, name, department FROM employees;
(3)视图查询
语法
sql复制代码
-- 与查询普通表语法相同
SELECT * FROM 视图名称 [WHERE 条件];
示例:查询订单视图
sql复制代码
-- 筛选 2023 年后的订单
SELECT * FROM customer_orders
WHERE order_date > '2023-01-01';
(4)视图删改
语法
sql复制代码
-- 删除视图
DROP VIEW IF EXISTS 视图名称;
-- 更新视图(需删除后重建)
DROP VIEW IF EXISTS employee_public;
CREATE VIEW employee_public AS
SELECT id, name, department, hire_date FROM employees; -- 新增入职日期列
(5)综合案例
场景:整合 products(产品表)、sales(销售表)生成月度销售汇总视图。
sql复制代码
-- 创建视图:月度销售汇总
CREATE VIEW monthly_sales_report AS
SELECT
strftime('%Y-%m', sale_date) AS month, -- 按月分组
products.name AS product_name,
SUM(sales.quantity) AS total_quantity,
SUM(sales.quantity * products.price) AS total_revenue
FROM sales
JOIN products ON sales.product_id = products.id
GROUP BY month, product_name;
查询视图:
sql复制代码
-- 获取 2024 年销售额最高的产品
SELECT product_name, total_revenue
FROM monthly_sales_report
WHERE month LIKE '2024-%'
ORDER BY total_revenue DESC
LIMIT 5;
-- 基础语法
CREATE INDEX [IF NOT EXISTS] 索引名
ON 表名(列名);
-- 示例:为 employees 表的 salary 列创建索引
CREATE INDEX idx_salary ON employees(salary);
唯一索引
sql复制代码
-- 强制列值的唯一性
CREATE UNIQUE INDEX [IF NOT EXISTS] 索引名
ON 表名(列名);
-- 示例:防止 users 表的 email 重复
CREATE UNIQUE INDEX uq_email ON users(email);
组合索引
sql复制代码
-- 基于多列的联合查询优化
CREATE INDEX 索引名
ON 表名(列1, 列2);
-- 示例:优化 orders 表的 user_id 和 status 联合查询
CREATE INDEX idx_user_status ON orders(user_id, status);
(3)索引查看
查看所有索引
sql复制代码
-- 查看当前数据库所有索引
SELECT name, sql FROM sqlite_master WHERE type = 'index';
-- 查看特定表索引
.indices 表名 -- SQLite 命令行工具专用语法
查看索引结构
sql复制代码
-- 显示索引的创建语句
.schema 索引名
(4)索引删除
sql复制代码
-- 基础语法
DROP INDEX [IF EXISTS] 索引名;
-- 示例:删除无效索引
DROP INDEX IF EXISTS idx_old;
(5)隐式索引
自动创建场景:主键(PRIMARY KEY)和唯一约束(UNIQUE)会自动生成唯一索引,例如:
sql复制代码
CREATE TABLE products (
id INTEGER PRIMARY KEY, -- 自动创建隐式索引
sku TEXT UNIQUE -- 自动创建隐式索引
);
(6)注意事项
性能权衡
适用场景:频繁的 WHERE、JOIN 或 ORDER BY 操作列
避免场景:小表(数据量 < 1000行)、高频写入列(降低 INSERT/UPDATE 速度)
组合索引优化
列顺序原则:将高频查询条件列放在左侧
示例:WHERE a=1 AND b=2 优先使用 (a,b) 而非 (b,a)
索引维护建议
定期重建:数据频繁修改后使用 REINDEX 索引名 优化性能
命名规范:建议使用 idx_表名_列名 格式提升可读性
3、触发器(Trigger)
(1)概念
在指定数据库事件(增/删/改)发生时自动执行预设操作,常用于:
数据校验:拦截非法值(如负数的库存)
级联更新:自动同步关联表数据(如订单表删除时清理明细表)
审计追踪:记录关键操作日志(如用户表修改时备份旧数据)
业务计算:实时更新统计字段(如订单总额变化时刷新客户总消费)
(2)类型详解
按触发时机分类
类型
语法关键字
执行时机
BEFORE 触发器
BEFORE INSERT/UPDATE/DELETE
在操作生效前执行,可修改或取消操作
AFTER 触发器
AFTER INSERT/UPDATE/DELETE
在操作生效后执行,适合日志记录
按触发粒度分类
类型
语法关键字
说明
行级触发器 (ROW)
FOR EACH ROW
默认类型,每影响一行数据触发一次
语句级触发器
❌ 不支持
SQLite 仅支持行级触发器
重要限制:SQLite 不支持 INSTEAD OF 触发器(常用于视图更新)
(3)核心语法
核心语法
sql复制代码
-- 基础语法
CREATE TRIGGER [IF NOT EXISTS] 触发器名
[BEFORE | AFTER] [INSERT | UPDATE | DELETE] ON 表名
FOR EACH ROW -- SQLite 仅支持行级触发器
[WHEN 条件]
BEGIN
-- 触发动作(SQL 语句)
END;
-- 删除触发器
DROP TRIGGER IF EXISTS 触发器名;
关键特性:
行级触发:每行数据变更都会激活触发器(FOR EACH ROW 必选)
临时表访问:
NEW.列名 → 获取 插入/更新后 的值
OLD.列名 → 获取 更新前/删除前 的值
异常处理:用 RAISE() 抛出错误(如 RAISE(ABORT, '错误消息'))
(4)案例演示
✅ 案例 1:数据验证(阻止非法操作)
sql复制代码
-- 禁止插入未来入职日期的员工
CREATE TRIGGER validate_hire_date
BEFORE INSERT ON employees
FOR EACH ROW
WHEN NEW.hire_date > date('now')
BEGIN
RAISE(ABORT, '入职日期不能是未来时间');
END;
效果:插入 hire_date = '2025-12-31' 时触发报错。
✅ 案例 2:自动审计日志
sql复制代码
-- 记录薪资变更历史
CREATE TRIGGER log_salary_changes
AFTER UPDATE ON salaries
FOR EACH ROW
BEGIN
INSERT INTO salary_audit(emp_id, old_salary, new_salary, change_time)
VALUES (OLD.emp_id, OLD.amount, NEW.amount, datetime('now'));
END;
效果:每次薪资更新时自动记录变更前后的值。
✅ 案例 3:级联删除关联数据
sql复制代码
-- 删除员工时同步删除相关记录
CREATE TRIGGER cascade_employee_delete
AFTER DELETE ON employees
FOR EACH ROW
BEGIN
DELETE FROM salaries WHERE emp_id = OLD.id;
DELETE FROM titles WHERE emp_id = OLD.id;
END;
效果:删除员工后自动清理薪资和职位表。
✅ 案例 4:自动计算字段
sql复制代码
-- 更新库存金额(数量 × 单价)
CREATE TRIGGER update_inventory_value
AFTER UPDATE OF quantity, price ON inventory
FOR EACH ROW
BEGIN
UPDATE inventory
SET total_value = NEW.quantity * NEW.price
WHERE id = NEW.id;
END;