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

SQLite 约束 (Constraints) 面试核心知识点

目录

1. 什么是数据库约束?

2. SQLite 中的主要约束类型

3. 约束详解与面试重点

3.1 PRIMARY KEY (主键约束)

3.2 NOT NULL (非空约束)

3.3 UNIQUE (唯一约束)

3.4 FOREIGN KEY (外键约束)

3.5 CHECK (检查约束)

3.6 DEFAULT (默认值约束)

4. 约束的定义级别


1. 什么是数据库约束?

面试官提问: “你能谈谈什么是数据库约束吗?为什么我们要使用它?”

回答要点:

数据库约束(Constraints)是在表的数据列上强制执行的规则。它们的主要目的是保证数据的完整性、准确性和可靠性

  • 目的:

    • 限制可以存储到表中的数据类型。

    • 防止无效或“脏”数据进入数据库。

    • 维护表与表之间的关系(参照完整性)。

  • 执行时机: 约束会在数据发生变化时(如 INSERT, UPDATE, DELETE)自动检查。如果操作违反了约束,该操作将被拒绝并报错。

2. SQLite 中的主要约束类型

SQLite 支持以下几种主要的约束:

  1. PRIMARY KEY (主键)

  2. NOT NULL (非空)

  3. UNIQUE (唯一)

  4. FOREIGN KEY (外键)

  5. CHECK (检查)

  6. DEFAULT (默认值)

3. 约束详解与面试重点

3.1 PRIMARY KEY (主键约束)

  • 定义: 用于唯一标识表中的每一行。

  • 特性:

    1. 隐含了 UNIQUENOT NULL 两个约束。

    2. 一张表最多只能有一个主键。

    3. 主键可以是单列,也可以是多列(称为“复合主键”)。

  • 示例:

    -- 单列主键
    CREATE TABLE Users (user_id INTEGER PRIMARY KEY, -- 隐含 UNIQUE 和 NOT NULLusername TEXT
    );-- 复合主键 (表级定义)
    CREATE TABLE OrderDetails (order_id INTEGER,product_id INTEGER,quantity INTEGER,PRIMARY KEY (order_id, product_id)
    );
  • ⭐ SQLite 面试重点:INTEGER PRIMARY KEYROWID

    • 在 SQLite 中,几乎所有的表都有一个隐藏的、唯一的64位有符号整数列,名为 ROWID

    • 如果你将一列定义为 INTEGER PRIMARY KEY(必须是 INTEGER,不能是 INTBIGINT),那么这一列实际上会成为 ROWID 的别名。

    • 好处: 这是 SQLite 中最高效的主键类型,因为它直接使用了底层的 ROWID 进行查找,速度极快。

    • 对比: 如果你定义 user_id TEXT PRIMARY KEY,SQLite 会为 user_id 单独创建一个索引,并且仍然在内部维护一个 ROWID

  • ⭐ SQLite 面试重点:AUTOINCREMENT 关键字

    • 误区: 很多人认为 INTEGER PRIMARY KEY 就会自动增长。它确实会自动生成一个唯一的 ID,但它可能重用之前删除过的行的 ID。

    • AUTOINCREMENT 的真正作用: 当你使用 INTEGER PRIMARY KEY AUTOINCREMENT 时,SQLite 会保证新插入的 ID 永远大于该表中曾经存在过的任何 ID。即使你删除了 ID 最大的行,下一个 ID 也会继续增长,绝不重用

    • 代价: AUTOINCREMENT 会带来额外的 CPU、内存和磁盘开销,因为它需要一个额外的 sqlite_sequence 表来跟踪每个表的最大 ID。

    • 面试结论: 除非你明确需要“ID 永不重用”的特性,否则只使用 INTEGER PRIMARY KEY 是最高效的选择。

    -- 推荐的高效方式 (可能会重用已删除的ID)
    CREATE TABLE Logs (log_id INTEGER PRIMARY KEY,message TEXT
    );-- 保证ID永不重用 (开销稍大)
    CREATE TABLE Invoices (invoice_id INTEGER PRIMARY KEY AUTOINCREMENT,amount REAL
    );

3.2 NOT NULL (非空约束)

  • 定义: 确保该列的值永远不能为 NULL

  • 示例:

    CREATE TABLE Products (product_id INTEGER PRIMARY KEY,name TEXT NOT NULL, -- 商品名不能为空price REAL NOT NULL   -- 价格不能为空
    );-- 尝试插入 NULL 将会失败
    INSERT INTO Products (name, price) VALUES (NULL, 9.99); -- 错误!

3.3 UNIQUE (唯一约束)

  • 定义: 确保该列(或多列组合)中的所有值都是唯一的。

  • 特性:

    • PRIMARY KEY 类似,但 UNIQUE 约束允许 NULL

    • ⭐ SQLite 面试重点:UNIQUE 约束的列中,你可以存储多个 NULL。SQLite (以及 PostgreSQL) 认为 NULL 不等于 NULL,所以多个 NULL 并不违反唯一性。 (注意:这在 SQL Server 或 Oracle 中行为不同)。

    • 一张表可以有多个 UNIQUE 约束。

  • 示例:

    CREATE TABLE Employees (emp_id INTEGER PRIMARY KEY,ssn TEXT UNIQUE,      -- 社保号必须唯一 (但允许有人没有社保号, 即 NULL)email TEXT UNIQUE     -- 邮箱也必须唯一
    );-- 以下插入在 SQLite 中是允许的
    INSERT INTO Employees (ssn) VALUES (NULL);
    INSERT INTO Employees (ssn) VALUES (NULL); -- 再次插入 NULL,仍然允许

3.4 FOREIGN KEY (外键约束)

  • 定义: 用于在两个表之间建立连接并强制实现参照完整性

  • 工作原理:

    • 它指定一个(或一组)列,称为“子列”,其值必须在另一张表(“父表”)的 PRIMARY KEYUNIQUE 列中存在,或者为 NULL

  • 示例:

    -- 1. 创建父表 (Departments)
    CREATE TABLE Departments (dept_id INTEGER PRIMARY KEY,dept_name TEXT NOT NULL
    );-- 2. 创建子表 (Employees)
    CREATE TABLE Employees (emp_id INTEGER PRIMARY KEY,name TEXT,dept_id INTEGER, -- 这是外键列FOREIGN KEY (dept_id) REFERENCES Departments (dept_id)ON DELETE SET NULL  -- 如果父表部门被删除,员工的部门设为NULLON UPDATE CASCADE -- 如果父表部门ID更新,员工的部门ID也跟着更新
    );
  • 外键动作 (ON DELETE / ON UPDATE):

    • NO ACTION / RESTRICT (默认):如果子表存在关联数据,禁止删除/更新父表。

    • SET NULL:父表数据变化时,子表对应列设为 NULL

    • SET DEFAULT:父表数据变化时,子表对应列设为默认值。

    • CASCADE:父表数据删除/更新时,子表关联的行也级联删除/更新

  • ⭐ SQLite 面试重点:启用外键

    • 在旧版本的 SQLite 中,外键支持默认是关闭的。在现代版本中(3.6.19 之后),通常在编译时默认开启。

    • 但为了保证兼容性和安全性,在建立连接后立即执行 PRAGMA foreign_keys = ON; 是一个非常好的习惯,这在面试中是加分项

    -- 在你的应用程序连接数据库后,应首先执行这个命令
    PRAGMA foreign_keys = ON;

3.5 CHECK (检查约束)

  • 定义: 允许你指定一个布尔表达式,INSERTUPDATE 的数据必须满足该表达式(即表达式结果为 TRUE)才能被写入。

  • 特性: SQLite 支持 CHECK 约束(但 MySQL 长期忽略它,直到 8.0)。

  • 示例:

    CREATE TABLE Products (id INTEGER PRIMARY KEY,name TEXT,price REAL CHECK (price > 0), -- 价格必须大于0discount REAL,-- 表级 CHECK 约束,可以引用多列CHECK (discount < price) -- 折扣必须小于价格
    );

3.6 DEFAULT (默认值约束)

  • 定义:INSERT 语句没有为该列提供值时,自动为其分配一个默认值。

  • 示例:

    CREATE TABLE Orders (order_id INTEGER PRIMARY KEY,order_date TEXT DEFAULT (DATE('now')), -- 使用函数作为默认值status TEXT DEFAULT 'Pending'          -- 使用常量作为默认值
    );-- 插入时,可以不指定 order_date 和 status
    INSERT INTO Orders (order_id) VALUES (101);
    -- 数据库中该行将自动填充 (..., '2025-10-29', 'Pending')

4. 约束的定义级别

约束可以在两个级别上定义:

  1. 列级约束 (Column-level):

    • 作为列定义的一部分。

    • NOT NULL 只能在列级定义。

    • 适用于:NOT NULL, PRIMARY KEY, UNIQUE, CHECK, DEFAULT, FOREIGN KEY (单列)。

    CREATE TABLE Example (id INTEGER PRIMARY KEY,email TEXT UNIQUE NOT NULL CHECK (length(email) > 5)
    );
  2. 表级约束 (Table-level):

    • 在所有列定义之后,单独定义。

    • 必须用于定义“复合主键”或“复合唯一/外键” (即约束涉及多于一列)。

    • 适用于:PRIMARY KEY, UNIQUE, CHECK, FOREIGN KEY

    CREATE TABLE Example (col1 INTEGER,col2 INTEGER,col3 TEXT,-- 表级定义PRIMARY KEY (col1, col2),UNIQUE (col2, col3)
    );
http://www.dtcms.com/a/544800.html

相关文章:

  • 使用J-Link Attach NXP S32K3导致对应RAM区域被初始化成0xDEADBEEF
  • 电子商务网站建设与维护展望分销系统微信
  • 变量与可变性
  • STM32 GPIO其他少见的库函数解析
  • 云栖实录|驰骋在数据洪流上:Flink+Hologres驱动零跑科技实时计算的应用与实践
  • 百度免费网站空间中国铁建股份有限公司
  • 【Git】版本更新
  • 网站建设与维护就业前景电商培训类网站模板下载
  • Android电池优化和前后台任务
  • 使用 Java 将 Excel 工作表转换为 CSV 格式
  • Kotlin基础类型扩展函数使用指南
  • 城市建设网站做印刷品去哪个网站
  • 怎么查网站到期时间php网站搭建环境
  • 汽车行业SCRM:企业微信+服务商模式破解汽车服务行业痛点的案例分析
  • 【第五章:计算机视觉-项目实战之推荐/广告系统】3.精排算法-(4)重排算法:MMR、DPP原理精讲
  • Xamarin.Forms菜鸟笔记--10.获取点击/滑动 Image位置
  • 网络环路“侦探”指南:如何快速定位与根除网络风暴
  • Android 自定义Switch
  • HBuilder 上架 iOS 应用全流程指南:从云打包到开心上架(Appuploader)上传的跨平台发布实践
  • PHP基础知识
  • Obsidian 入门教程
  • 响应式购物网站模板广州网站优化电话
  • 中山 网站建设 骏域做ag视频大全网站
  • Vue二进制数据渲染成图片
  • 未来智能网联汽车的网络安全档案建立方法
  • 防止表单重复提交功能简单实现
  • 网络安全等级保护测评高风险判定实施指引(试行)--2020与2025版对比
  • Squid 可观测性最佳实践
  • 【深度学习新浪潮】DeepSeek-OCR深度解析:视觉-文本压缩驱动的新一代OCR技术革命
  • 官方网站建设投标书网站建设包含哪些