SQLite03-数据库管理
1、数据库管理
(1)数据库创建
- 若
test.db 不存在,则自动创建并进入 SQLite 命令行交互模式。
- 若
test.db 已存在,则直接打开该数据库。
sqlite3 test.db # 例如:sqlite3 test.db
(2)数据库查看
.database
2、数据表增删改
(1)创建表(CREATE TABLE)
CREATE TABLE [IF NOT EXISTS] 表名 (
列名1 数据类型 [约束条件],
列名2 数据类型 [约束条件],
...
[PRIMARY KEY (列名)],
[FOREIGN KEY (列名) REFERENCES 其他表(列名)]
);
CREATE TABLE IF NOT EXISTS employees (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER CHECK (age >= 18),
department_id INTEGER,
FOREIGN KEY (department_id) REFERENCES departments(id)
);
- 关键说明:
- 数据类型:支持
INTEGER、TEXT、REAL(浮点数)、BLOB(二进制)等。
- 约束:
PRIMARY KEY:主键(支持 AUTOINCREMENT 自增)。
NOT NULL:禁止空值。
UNIQUE:列值唯一。
CHECK:自定义条件(如 age >= 18)。
FOREIGN KEY:外键关联。
(2)修改表(ALTER TABLE)
- SQLite 的
ALTER TABLE 功能有限,仅支持以下操作:
-- 重命名表
ALTER TABLE 旧表名 RENAME TO 新表名;
-- 示例:ALTER TABLE employees RENAME TO staff;
-- 添加列
ALTER TABLE 表名 ADD COLUMN 列名 数据类型 [约束];
-- 示例:ALTER TABLE staff ADD COLUMN email TEXT UNIQUE;
(3)删除表(DROP TABLE)
- 注意:删除表会连带删除所有数据和索引,操作需谨慎。
DROP TABLE [IF EXISTS] 表名;
-- 示例:DROP TABLE IF EXISTS temp_data;
(4)限制与解决方案
- 问题:如何实现"删除列"或"修改列"?
- 由于 SQLite 不支持直接删除列,需通过以下步骤间接实现:
- 创建新表(含目标列结构)。
- 将旧表数据导入新表。
- 删除旧表并重命名新表。
- 示例(删除
staff 表的 age 列):
-- 步骤1:创建新表(不含 age 列)
CREATE TABLE new_staff (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
);
-- 步骤2:复制数据
INSERT INTO new_staff (id, name, email)
SELECT id, name, email FROM staff;
-- 步骤3:替换表
DROP TABLE staff;
ALTER TABLE new_staff RENAME TO staff;
3、数据类型
(1)数据类型
- NULL:表示一个空值或缺失的值。这是 SQL 标准的一部分,表示没有值。
- INTEGER:用于存储整数值。SQLite 支持 1、2、3、4、6 和 8 字节的整数类型,具体使用哪种取决于插入的值的大小。实际上,SQLite 并不区分这些不同的整数类型名称,它们都会被映射到
INTEGER 类型。例如:
TINYINT
SMALLINT
MEDIUMINT
INTEGER
BIGINT
- REAL:
- 用于存储浮点数,即带有小数点的数字。这通常对应于 8 字节的 IEEE 浮点数(双精度)。
- 也可以使用
FLOAT 或 DOUBLE 来声明浮点数类型,但它们同样会被映射到 REAL 类型。
- TEXT:
- 用于存储文本字符串。SQLite 使用 UTF-8、UTF-16BE 或 UTF-16LE 编码来存储文本,具体取决于数据库的编码设置。
- 你可以使用
CHARACTER(n)、VARCHAR(n) 或 TEXT 来声明文本类型,其中 n 是字符的最大长度,但这只是一个提示,SQLite 不会强制执行长度限制。
- BLOB:用于存储二进制大对象(Binary Large Object),如图像、音频文件等。BLOB 类型的数据是以原始字节形式存储的,不会进行任何解释或转换。
- NUMERIC:这是一个通用的类型亲和性,适用于需要精确数值存储的情况,如货币值。当 SQLite 遇到
NUMERIC 类型时,它会尝试将数据存储为最合适的类型(INTEGER 或 REAL),如果不行,则作为 TEXT 存储。
(2)类型亲和性
- SQLite 支持的数据类型相对简单,SQLite 采用了一种更为灵活的动态类型系统,称为"类型亲和性"(Type Affinity)。这意味着在 SQLite 中,列可以存储任何类型的值,但会根据列的声明类型尝试将数据转换为最合适的类型。
- 主要的类型亲和性包括:
- TEXT 亲和性:适用于
TEXT、CHAR、CLOB 等类型。
- NUMERIC 亲和性:适用于
NUMERIC、DECIMAL、BOOLEAN、DATE、DATETIME 等类型。
- INTEGER 亲和性:适用于
INTEGER 类型。
- REAL 亲和性:适用于
REAL、FLOA、DOUBLE 等类型。
- NONE 亲和性:适用于未指定类型或使用了非标准类型的情况。在这种情况下,SQLite 不会对插入的值进行类型转换。
- 由于 SQLite 的动态类型系统,实际上你可以在任何类型的列中存储任何类型的数据。例如,你可以在一个声明为
INTEGER 的列中存储文本字符串,尽管这不是推荐的做法,因为这样做可能会导致性能问题和逻辑错误。
4、约束类型
(1)概述
- 数据库约束(Constraints)是关系型数据库中用于强制数据完整性的规则,限制表中数据的格式、关系和有效性。
- 在 SQLite 中,约束主要分为列级(作用于单列)和表级(作用于多列或整表)两种类型。
(2)约束的关键特性
- 组合约束
- 单列可叠加多个约束(如
NOT NULL + UNIQUE);
- 主键可为多列组合(复合主键):
PRIMARY KEY (col1, col2)。
- 外键的级联操作
- 支持
ON DELETE CASCADE(删除主表记录时同步删除从表关联记录)等联动规则。
- 约束冲突处理
- 违反约束时 SQLite 默认报错中止操作,可通过
INSERT OR IGNORE 等语句忽略冲突。
- SQLite 的特殊性
- 主键允许
NULL:需显式声明 NOT NULL 避免主键为空;
- 外键默认关闭:需执行
PRAGMA foreign_keys = ON; 启用。
(3)约束的应用价值
- 数据准确性:阻挡无效数据入库(如负数年龄、空用户名);
- 关系一致性:通过外键维护表间逻辑关联(如用户与订单);
- 业务规则落地:用
CHECK 实现复杂逻辑(如折扣率范围验证)。
(4)基本约束案例
NOT NULL 约束:强制列不接受 NULL 值,确保数据完整性。
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL -- 姓名不可为空
);
UNIQUE 约束:确保列中所有值唯一(允许多个 NULL 值)。
CREATE TABLE products (
sku TEXT UNIQUE, -- SKU 码必须唯一
price REAL
);
PRIMARY KEY 约束:
- 唯一标识表中的记录。
- 每个表只能有一个主键(可为单列或复合键)。
- 注意:SQLite 主键允许
NULL(与其他数据库行为不同)。
CHECK 约束:限制列值的范围或条件。
CREATE TABLE employees (
age INTEGER CHECK (age >= 18), -- 年龄必须 ≥18
salary REAL CHECK (salary > 0)
);
DEFAULT 约束:插入数据时,若未指定值则自动填充默认值。
CREATE TABLE orders (
create_date DATE DEFAULT CURRENT_DATE -- 默认当天日期
);
(5)关系型约束案例
FOREIGN KEY 约束 :强制表间引用完整性,确保外键值匹配另一表的主键。
CREATE TABLE orders (
order_id INTEGER PRIMARY KEY,
user_id INTEGER,
FOREIGN KEY (user_id) REFERENCES users(id) -- 关联用户表
);
(6)添加与删除约束
-- 添加新约束(ALTERTABLE 仅支持部分操作)
ALTER TABLE 表名 ADD COLUMN 列名 数据类型 CHECK(条件); -- 添加列时带约束
-- 删除约束需重建表(SQLite 原生不支持直接删除约束)
-- 步骤:① 创建临时表 → ② 复制数据 → ③ 删除原表 → ④ 重命名临时表。