# 1. INSTEAD OF 触发器在视图可更新性中的作用,如何通过触发器实现复杂视图的 INSERT/UPDATE/DELETE? A INSTEAD OF 触发器在基表上额外执行 B INSTEAD OF 触发器只能用于 DELETE C INSTEAD OF 触发器用函数体"替代"视图上的 DML,自行拆分写入多张基表(含 JOIN/聚合的复杂视图因此可写),通过 NEW/OLD 访问视图行,MySQL 不支持视图 INSTEAD OF ✓ 正确答案 D 复杂视图无法实现可写
# 2. PostgreSQL 中 AFTER 触发器与 BEFORE 触发器的执行顺序与可见性,BEFORE 可修改 NEW、AFTER 只能读取。 A AFTER 触发器可以修改 NEW B AFTER 返回 NULL 可以阻止写入 C BEFORE 触发器在约束之后执行 D 顺序为 BEFORE(可修改 NEW,行级约束检查看到修改后值)→ 写入 → AFTER(NEW/OLD 只读,用于审计联动,语句结束时触发);外键在语句结束时检查,BEFORE 返回 NULL 阻止该行写入 ✓ 正确答案
# 3. 事件触发器(Event Trigger)在 PostgreSQL 中的 ddl_command_start、ddl_command_end、sql_drop 事件的应用? A 事件触发器挂在数据库级响应 DDL 事件:ddl_command_start 可阻止 DDL、ddl_command_end 记录成功变更、sql_drop 归档被删对象,用于 DDL 审计、防护与变更追踪 ✓ 正确答案 B 事件触发器作用于表的行 DML C 事件触发器可以触发自身递归 D 事件触发器只能用于 DML
# 4. 定时事件(Scheduled Event),MySQL EVENT、PostgreSQL pg_cron、SQL Server Agent Job 的对比与等价功能? A MySQL 用 EVENT(需开启 event_scheduler)、PostgreSQL 用 pg_cron 扩展、SQL Server 用 Agent Job(功能最全);数据库内调度随实例存活,复杂编排应用外部调度平台并配日志告警 ✓ 正确答案 B PostgreSQL 原生内置定时调度器 C 三库定时任务语法一致 D MySQL 事件自动在从库执行
# 5. 触发器对复制的影响,行触发器 vs 语句触发器在主从复制中的差异? A 语句级复制重放语句使副本触发器自然执行,行级复制复制行事件后副本触发器可能再次执行(双写);PG 物理复制不执行副本触发器,逻辑复制默认执行可跳过 ✓ 正确答案 B 副本上的触发器从不执行 C 行级复制不复制触发器产生的变更 D 触发器与复制无关
# 6. 触发器的递归触发与无限循环风险,A 触发器更新 B 表导致 B 触发器又更新 A 如何防护? A 数据库总能自动终止触发器递归 B 触发器不能互相触发 C A→B→A 的触发器互相写表会无限递归(MySQL 默认递归直到死锁报错、SQL Server 默认禁递归、PG 需防重入);防护用会话开关、哨兵标志、深度计数并保持触发器依赖单向化 ✓ 正确答案 D 递归只在同一表发生
# 7. 触发器(Trigger)的分类体系,BEFORE/AFTER/INSTEAD OF、ROW/STATEMENT、INSERT/UPDATE/DELETE/TRUNCATE 的笛卡尔积组合如何声明? A 分类维度为时机(BEFORE/AFTER/INSTEAD OF)×级别(ROW/STATEMENT)×事件(INSERT/UPDATE/DELETE/TRUNCATE);TRUNCATE 仅语句级、INSTEAD OF 仅行级视图,MySQL 只有行级触发器且无 TRUNCATE ✓ 正确答案 B TRUNCATE 支持行级触发器 C 所有组合都合法 D INSTEAD OF 只能用于基表
# 8. PostgreSQL 中 WHEN 子句(条件触发器)的语法与执行效率? A WHEN 条件在函数内部判断 B WHEN 在触发函数调用前按行求值(不满足条件的行不调用函数),比函数内 IF 少一次函数调用开销,适合大部分行不触发的场景,WHEN 不能包含子查询 ✓ 正确答案 C WHEN 可以包含子查询 D WHEN 只能用于语句级触发器
# 9. 为何在 OLTP 高并发系统中应谨慎使用触发器?同步开销、调试困难、隐式逻辑如何避免? A 触发器适合承载复杂业务逻辑 B 触发器逻辑与应用代码一样可见 C 触发器不影响写入性能 D 触发器在写入路径同步执行(批量逐行触发放大延迟)、逻辑隐式难排查难测试,OLTP 应只保留小而明确的触发器(审计/时间戳),大联动异步化或用 CDC/约束替代 ✓ 正确答案
# 10. CREATE TRIGGER 的基本语法示例(BEFORE INSERT 触发器)? A MySQL 触发器需要独立触发器函数 B BEFORE 触发器必须 RETURN NULL C PostgreSQL 先 CREATE FUNCTION 再 CREATE TRIGGER ... EXECUTE FUNCTION 挂载,BEFORE INSERT 行级触发器通过修改 NEW 并 RETURN NEW 实现写入前清洗/填默认值 ✓ 正确答案 D 触发器函数与触发器是同一概念
# 11. MySQL EVENT 调度器如何启用?SET GLOBAL event_scheduler = ON? A 启用用 SET GLOBAL event_scheduler = ON(即时但重启失效),持久化用配置文件或 8.0 的 SET PERSIST;事件不自动复制到从库、实例宕机期间任务不执行 ✓ 正确答案 B event_scheduler 默认启用 C SET PERSIST 在 5.7 可用 D 事件会自动在从库执行
# 12. MySQL 中如何创建 AFTER UPDATE 触发器? A MySQL 触发器有独立的触发器函数 B CREATE TRIGGER ... AFTER UPDATE ON t FOR EACH ROW + 内联函数体(BEGIN...END,DELIMITER 包裹);UPDATE 中 NEW/OLD 分别表示新/旧行,用于审计、汇总维护,MySQL 只有行级触发器 ✓ 正确答案 C MySQL 触发器支持语句级 D AFTER 触发器中修改 NEW 会影响写入值
# 13. PostgreSQL 中 CONSTRAINT TRIGGER 与普通 TRIGGER 的区别? A 约束触发器专用于实现约束语义:支持 DEFERRABLE(默认 INITIALLY DEFERRED 提交时检查,可用 SET CONSTRAINTS 切换),只支持 AFTER,用于跨行/跨表不变式的延迟校验 ✓ 正确答案 B 约束触发器可以 BEFORE 且不可延迟 C 约束触发器与普通触发器完全等价 D 约束触发器只能立即执行
# 14. PostgreSQL 中 NEW 与 OLD 关键字的语义? A INSERT 触发器中 NEW 与 OLD 都存在 B DELETE 触发器有 NEW C AFTER 触发器中可修改 NEW D NEW 是操作后的行(INSERT/UPDATE 可用)、OLD 是操作前的行(UPDATE/DELETE 可用);BEFORE 中可修改 NEW(写入修改后值)而 OLD 只读,RETURN NULL 可跳过该行 ✓ 正确答案
# 15. PostgreSQL 中触发器函数的 LANGUAGE 必须是 plpgsql 吗? A 触发器函数只能用 plpgsql B 触发器函数可用任意支持语言(plpgsql 最常见、SQL 单语句受限、C 内建、plpython 等),硬性要求是 RETURNS trigger 且无参数,NEW/OLD 语义语言无关 ✓ 正确答案 C 触发器函数必须返回 void D LANGUAGE SQL 触发器函数支持多语句
# 16. 一个 BEFORE INSERT 触发器能否阻止 INSERT 操作? A RETURN NULL 会中止整个语句 B BEFORE 行级触发器 RETURN NULL 静默跳过该行(不报错、其余行继续),RAISE EXCEPTION 显式拒绝并中止语句;MySQL 无 RETURN 机制需用 SIGNAL 抛错 ✓ 正确答案 C AFTER 触发器可以阻止插入 D RETURN NULL 只影响语句级触发器
# 17. 如何在 INFORMATION_SCHEMA 中查询所有触发器? A information_schema.triggers 提供名称/事件/表/时机/级别等字段(MySQL 含函数体、PG 的 ACTION_STATEMENT 为空),PG 更常用 pg_trigger 位掩码查询、MySQL 可用 SHOW TRIGGERS ✓ 正确答案 B 所有数据库都只有 information_schema.triggers C Oracle 使用 information_schema.triggers D 触发器无法按表过滤查询
# 18. 触发器与 CDC(Change Data Capture)的取舍? A 触发器做变更捕获简单且与事务强一致,但侵入写入路径且无法捕获 DDL/TRUNCATE;CDC(解析 binlog/WAL)无侵入、实时、可捕获结构变更,用于异步同步但需日志保留与消费幂等 ✓ 正确答案 B 触发器可以捕获 DDL 与 TRUNCATE C CDC 与业务事务强一致 D 两者能力完全重叠
# 19. 触发器与约束(CHECK)的取舍准则是什么? A 能声明式表达就用约束(CHECK/唯一/外键:单行、性能好、可移植),跨行/跨表/聚合/动态规则才用触发器(RAISE 校验),触发器中仍应用约束兜底 ✓ 正确答案 B 触发器应该替代所有约束 C CHECK 可以跨表引用 D 约束性能比触发器差
# 20. 序列在分布式环境下的失效,分库分表后如何保证全局唯一?雪花 ID、Leaf、UUID 的对比? A 单库序列在分库分表后各片重复,需全局方案:雪花 ID(64 位时间戳+机器+序列,趋势递增但怕时钟回拨)、Leaf 号段(DB 分配区间)、UUID(v4 随机/v7 有序);主流选雪花或号段 ✓ 正确答案 B 分库分表后各片自增序列仍然全局唯一 C UUID v4 顺序性好 D 雪花 ID 不需要处理时钟回拨
# 21. 序列的 currval、nextval、setval 函数调用语义与可见性规则? A currval 返回全局最近值 B nextval 随事务回滚 C nextval 原子推进并返回(全局单调、不回滚),currval 只返回本会话最近 nextval 值(未调用报错),setval 全局立即生效;迁移后需 setval 对齐到 MAX(id) ✓ 正确答案 D setval 只在当前会话生效
# 22. 序列的并发安全机制,nextval() 的原子性、CACHE 1/100 的差异、重启时的空洞如何避免? A CACHE 越大空洞越少 B nextval 原子递增保证并发唯一(PG 无锁原子、MySQL 自增锁),CACHE 预分配提升性能但崩溃会丢未用值产生空洞;序列只保证唯一递增不保证连续,连续需求需占号回填机制 ✓ 正确答案 C 事务回滚会使 nextval 回退 D 序列保证值连续
# 23. 序列(Sequence)的本质是什么?它是表的对象还是独立的 schema 对象?PostgreSQL 的 CREATE SEQUENCE 与 MySQL 的 AUTO_INCREMENT 的根本差异? A 序列是独立的 schema 级计数器对象(PG/Oracle 可跨表共享、独立授权与删除),MySQL 的 AUTO_INCREMENT 是表内列属性(无独立对象、不可共享);PG 用 nextval 获取、MySQL 省略列自动分配 ✓ 正确答案 B MySQL 的 AUTO_INCREMENT 是独立对象 C PostgreSQL 的序列依附于表存在 D 两模型完全等价
# 24. 生成列(Generated Column)在 MySQL 5.7+、PostgreSQL 12+、SQL Server 中的实现差异,VIRTUAL vs STORED 的取舍? A VIRTUAL 列占用物理存储 B 生成列表达式可以是 VOLATILE C 生成列可以手工赋值 D 生成列由表达式自动计算:MySQL 支持 VIRTUAL(不存储、可索引)与 STORED(物化、可作外键/分区键),PostgreSQL 仅 STORED、SQL Server 用 PERSISTED;表达式必须确定性,按读写频率取舍 ✓ 正确答案
# 25. PostgreSQL 中序列关联列的实现(DEFAULT nextval('seq'))与 MySQL AUTO_INCREMENT 的等价写法? A MySQL 的 AUTO_INCREMENT 是独立序列对象 B PostgreSQL 用 DEFAULT nextval('seq')、SERIAL 或标准 IDENTITY(推荐)实现自增,MySQL 用 AUTO_INCREMENT 列属性;取回新 id 分别用 RETURNING/currval 与 LAST_INSERT_ID() ✓ 正确答案 C PG 的序列不能跨表共享 D IDENTITY ALWAYS 允许手工插入任意 id
# 26. 为什么 MySQL 的 AUTO_INCREMENT 在某些场景下会“空洞”(自增不连续)? A 事务回滚会使自增值回退复用 B 自增分配不回滚(回滚作废不复用)、删除不复用、批量插入按区间分配中断即跳跃、显式插入使计数器跳变,因此空洞正常;自增只保证唯一递增不保证连续 ✓ 正确答案 C MySQL 保证自增连续 D 删除行后自增值自动复用
# 27. PostgreSQL 中 serial、bigserial、smallserial 的差异? A serial/bigserial/smallserial 是"整数列+自动序列+默认 nextval+OWNED BY"的语法糖(类型为 INT/BIGINT/SMALLINT),默认推荐 bigserial 或标准 IDENTITY 写法 ✓ 正确答案 B serial 是独立的原生类型 C serial 底层是 VARCHAR D 三种 serial 类型完全相同
# 28. PostgreSQL 中如何获取当前序列值? A currval 返回全局最新值 B 并发下可基于 last_value 预测下一个值 C last_value 一定等于下一个 nextval D currval 只返回本会话最近 nextval 的值(未调用报错),pg_sequences 的 last_value 是持久值(CACHE 下可能落后于内存已分配值);取刚插入 id 推荐 RETURNING ✓ 正确答案
# 29. UUID 与自增 ID 在主键场景下的取舍? A UUID 的索引性能优于自增 B UUID v4 顺序性好 C 自增 BIGINT 紧凑有序但分布式不唯一,UUID 全局唯一可离线生成但 v4 随机导致索引页分裂与膨胀;单库用自增、分布式用 UUID v7 或雪花 ID,避免 UUID v4 ✓ 正确答案 D 自增 ID 防枚举
# 30. 为什么序列的 nextval 不随事务回滚回退(无事务语义),及其对自增 ID 空洞的影响 A nextval 分配即生效、永不回退(并发唯一分配器的必然设计,回滚只产生空洞),空洞不影响主键与索引,连续编号需求需占号回填机制而非序列 ✓ 正确答案 B nextval 随事务回滚回退 C 序列状态参与 MVCC D 回拨序列可以安全填洞
# 31. 为什么主键不建议使用 UUID v1 而推荐 v7? A UUID v1 时间戳大端在前,天然有序 B v4 的顺序性优于 v7 C v1 与 v7 结构相同 D UUID v1 含 MAC 地址(隐私)且时间戳低序在前(乱序、索引差),v7 用毫秒时间戳大端在前(字典序=时间序,索引友好)加随机位,新系统主键应选 v7 ✓ 正确答案
# 32. 序列在复制场景下的行为差异(PG 物理复制、MySQL 主从)? A PG 物理复制经 WAL 同步序列(切换无忧)、逻辑复制不复制序列(订阅端需 setval 对齐);MySQL ROW 模式自增值随 binlog、STATEMENT 模式需 auto_increment_increment/offset 错开 ✓ 正确答案 B PG 逻辑复制会自动同步序列状态 C MySQL 行级复制不复制自增值 D 序列与复制无关
# 33. 域(DOMAIN)在 PostgreSQL 中的实现,CREATE DOMAIN 与 CREATE TYPE 的差异,DOMAIN 可携带约束吗? A CREATE DOMAIN 基于现有类型叠加规则(CHECK 用 VALUE 引用、NOT NULL、DEFAULT),列声明即复用规则;与 CREATE TYPE(新存储类型、需 IO 函数)本质不同 ✓ 正确答案 B DOMAIN 需要自定义输入输出函数 C DOMAIN 是全新的存储类型 D DOMAIN 不能携带 CHECK
# 34. 复合类型(Composite Type)在 PostgreSQL 中的用法,声明、构造(ROW())、访问(.field)、比较语义。 A 复合类型不支持比较 B 复合类型的字段可以单独建约束 C 复合类型用 CREATE TYPE 或表定义,ROW() 构造、点号访问(复合列需括号);比较按字段逐字段字典序(任一字段 NULL 使整体比较为 NULL),字段级约束需拆表 ✓ 正确答案 D ROW() 只能用于插入
# 35. 数组类型(Array)在 PostgreSQL 中的原生支持,构造(ARRAY[])、访问([i])、数组操作符(&&、@>、<@)。 A 数组下标从 0 开始 B 数组支持元素级唯一约束 C 数组用 ARRAY[]/字面量构造、[i] 访问(1 起始、越界返回 NULL);@> 包含、<@ 被包含、&& 重叠、= ANY 判元素,GIN 索引加速包含与重叠查询 ✓ 正确答案 D 数组查询无法走索引
# 36. 枚举类型(ENUM)在 PostgreSQL、MySQL 中的实现差异,枚举值的存储大小、修改成本、索引支持。 A MySQL 的 ENUM 是独立类型对象 B ENUM 值可以自由删除 C PostgreSQL 的 ENUM 是类型级对象(4 字节存储、ADD VALUE 追加即可),MySQL 是列级内联(1-2 字节序号、修改列表需重建表),两者都按定义序排序并支持索引;动态字典应改用字典表 ✓ 正确答案 D 两库 ENUM 修改成本相同
# 37. 范围类型(Range Type)在 PostgreSQL 中的原生支持,int4range、numrange、tsrange、daterange 的边界(inclusive/exclusive)。 A 范围类型只支持整数 B 范围类型不支持索引 C 范围类型(int4range/tsrange/daterange 等)用 [ 闭 ( 开表达边界,支持 @> 包含、&& 重叠、-|- 邻接等操作符,GiST 索引与 EXCLUDE 约束可实现区间不重叠 ✓ 正确答案 D 所有范围边界默认都是闭的
# 38. PostgreSQL 中如何删除自定义类型?DROP TYPE 的级联影响? A DROP TYPE 默认 RESTRICT(有依赖报错),CASCADE 会级联删除引用该类型的列(数据随之丢失)与依赖函数;安全做法是先查 pg_depend、改列类型解除依赖后再删 ✓ 正确答案 B CASCADE 只删除类型定义 C 删除类型不影响表列 D DROP TYPE 不可回滚
# 39. 自定义类型的输入/输出函数(IO function)的实现步骤是什么? A 所有自定义类型都需手写 IO 函数 B IO 函数可以是 VOLATILE C 基础类型需输入(cstring→内部)与输出(内部→cstring)函数,CREATE TYPE 时声明 INPUT/OUTPUT、INTERNALLENGTH、PASSEDBYVALUE、ALIGNMENT 等;枚举/复合/范围类型无需自写 IO ✓ 正确答案 D 输入函数不需要错误校验
# 40. JSON 与 JSONB 的查询性能差异? A JSON 的查询性能优于 JSONB B JSON 原样存文本(写入快、访问时解析、无 GIN 索引),JSONB 存规范化二进制(写入慢、查询快、支持 GIN 与存在性操作符),默认选 JSONB ✓ 正确答案 C JSONB 保留键顺序与重复键 D 两者索引能力相同
# 41. LTREE 类型在 PostgreSQL 中的用途? A LTREE 是邻接表建模 B LTREE 不支持索引 C LTREE(扩展)用点分标签的物化路径表达树节点,<@/@> 判祖先后代、~ lquery 匹配、GiST 索引加速,适合读多(频繁查子树)场景;频繁移动子树用邻接表+递归 CTE ✓ 正确答案 D LTREE 与 TEXT 物化路径完全相同
# 42. PostgreSQL 中如何创建复合类型? A CREATE TYPE 名 AS (字段列表) 定义命名字段结构,可用于复合列(ROW 构造、点号访问)、函数返回与数组参数;ALTER TYPE 可增删属性,字段级约束需拆表或用表达式索引 ✓ 正确答案 B 复合类型是存储格式别名 C 复合类型不能用于表列 D 复合类型字段可以单独建约束
# 43. PostgreSQL 的 citext 类型的作用是什么? A citext 存储时转为小写 B citext 是大小写不敏感文本类型:存储保留原样、比较按 lower 语义(=、UNIQUE、GROUP BY 自动不敏感),比手动 lower() 方案不易漏写;比较有 lower 调用开销、行为受排序规则影响 ✓ 正确答案 C citext 显示时强制小写 D citext 与 TEXT 完全等价
# 44. PostgreSQL 的 hstore 类型(键值对)的使用场景? A hstore 支持嵌套 JSON B hstore 与 JSONB 完全等价 C hstore 值支持数字类型 D hstore 存扁平字符串键值对(-> 访问、? 存在、@> 包含、GIN 索引),适合稀疏动态属性与 KV 检索;需要嵌套/类型/标准支持时用 JSONB(功能超集) ✓ 正确答案
# 45. PostgreSQL 的 tsvector 类型与全文检索的关系? A LIKE 与 tsvector 检索能力相同 B tsvector 是分词/词干化后的词项向量(配合 tsquery 与 @@ 匹配、GIN 索引、ts_rank 排名),是 PostgreSQL 全文检索的核心;中文需分词扩展,海量场景用 Elasticsearch ✓ 正确答案 C tsvector 检索无法走索引 D tsquery 是存储类型
# 46. UUID 类型与 TEXT 存储 UUID 的性能对比? A TEXT 存储 UUID 更省空间 B UUID 类型 16 字节、TEXT 36 字节:UUID 类型索引更小、比较更快、行更窄缓存更好,且强制格式校验;TEXT 存 UUID 是反模式(仅遗留场景) ✓ 正确答案 C 两种存储性能完全一致 D TEXT 存储有格式校验
# 47. 自定义类型如何与 ORM 框架(SQLAlchemy、Hibernate)集成? A ORM 自动支持所有数据库自定义类型 B 自定义类型无法映射到 ORM C SQLAlchemy 用 TypeDecorator 与方言类型(ENUM/ARRAY/JSONB/UUID)、Hibernate 用 AttributeConverter/UserType 或 hibernate-types 库集成自定义类型;需保证 DDL 一致、读写可逆与 NULL 处理 ✓ 正确答案 D UserType 是 JPA 标准接口
# 48. MySQL InnoDB 在线加索引(ALGORITHM=INPLACE、LOCK=NONE)的实现细节。 A ALGORITHM=COPY 不锁表 B 加二级索引支持 ALGORITHM=INPLACE + LOCK=NONE:扫描主键构建索引树、期间 DML 记录到 online log 后回放合并,不重建整表;不支持时自动降级(COPY 或更高锁级别) ✓ 正确答案 C INPLACE 加索引会复制整表数据 D 在线 DDL 不需要临时空间
# 49. PostgreSQL CREATE INDEX CONCURRENTLY 的工作原理与失败回滚机制? A 并发建索引会阻塞写入 B CIC 通过"扫描构建 + 等待并发事务 + 合并变更"实现不阻塞 DML 的建索引(锁 SHARE UPDATE EXCLUSIVE),失败后残留下 INVALID 索引需手工 DROP 清理 ✓ 正确答案 C CIC 可以在事务块内执行 D CIC 失败会自动删除索引
# 50. 唯一索引(UNIQUE INDEX)与唯一约束(UNIQUE CONSTRAINT)的实现差异,本质相同但约束名与索引名分离。 A 唯一约束不需要底层索引 B 唯一索引可以延迟检查 C 两者语义等价(底层都是唯一 B 树),差异在元数据:唯一约束自动伴随创建同名索引、可被外键引用与延迟检查;唯一索引无约束语义但支持部分/表达式唯一 ✓ 正确答案 D 外键不能引用唯一索引列
# 51. 索引在 PostgreSQL、MySQL、SQL Server 中的创建语法差异,CREATE INDEX 的并行选项、ONLINE、CONCURRENTLY。 A 三库在线建索引语法一致 B PostgreSQL 用 CONCURRENTLY(无 ONLINE 关键字、支持部分/表达式/INCLUDE),MySQL 用 ALGORITHM/LOCK(前缀键、无部分索引),SQL Server 用 ONLINE/MAXDOP(过滤索引、INCLUDE);并行构建支持各不相同 ✓ 正确答案 C MySQL 支持部分索引 D SQL Server 无过滤索引
# 52. 索引膨胀(Index Bloat)的原因与检测,pgstat、pgstattuple 在 PostgreSQL 中的应用。 A 普通 VACUUM 会把索引空间归还文件 B 膨胀不影响查询性能 C 膨胀源于 MVCC 更新产生的死元组与清理不及时;pgstattuple 的 avg_leaf_density 与死元组可精确检测,REINDEX(可 CONCURRENTLY)压缩重建,预防靠 fillfactor 与及时 vacuum ✓ 正确答案 D pg_stat_user_indexes 直接给出膨胀率
# 53. 组合索引(Composite Index)的列顺序对查询效率的影响,最左前缀原则在不同数据库中的实现细节。 A 范围条件列应放最前 B 组合索引按列顺序逐级排序,查询需满足最左前缀(等值列在前、范围列在后、高选择性在前);MySQL 8.0 有 skip scan/ICP、SQL Server 有索引交集、PG 靠部分索引与多列统计补充 ✓ 正确答案 C 列顺序与查询无关 D 不含第一列的查询总能走组合索引
# 54. 表达式索引(Expression Index)的使用场景,LOWER(col)、date_trunc('day', ts)作为索引键。 A 表达式索引把表达式(如 LOWER(col)、date_trunc('day', ts))作为索引键,解决函数包裹列无法走索引的问题;表达式必须 IMMUTABLE 且查询需写相同表达式,能改写成范围查询时应优先改写 ✓ 正确答案 B 表达式索引可以包含 volatile 函数 C 查询写不同形式的等价表达式也能命中 D 表达式索引与普通索引完全相同
# 55. 部分索引(Partial Index)的价值,WHERE 子句过滤的小集合数据如何用部分索引加速? A 部分索引包含全表所有行 B 部分索引可以用于任意查询 C 部分索引(WHERE 条件)只索引满足条件的行:体积小、命中率高,适合软删除/状态子集等"小集合高频查询";查询谓词需包含索引条件才匹配,MySQL 无部分索引 ✓ 正确答案 D 部分索引体积与全量索引相同
# 56. 索引的存储参数(fillfactor)在 B-Tree 上的写入性能影响? A fillfactor 是页初始填充率:随机插入/高频更新场景设低值(60-85)减少页分裂、顺序插入用 100 最紧凑,是"体积与写入速度"的折中,重建后才按新参数生效 ✓ 正确答案 B fillfactor 越低索引越大且写入越慢 C fillfactor 只影响查询不影响写入 D 所有场景都应设 100
# 57. BRIN 索引的适用场景,在天然有序的大表上如何用最小元数据加速范围查询,其选择性不足的代价与索引体积收益如何衡量? A BRIN 适合随机键点查 B BRIN 为物理有序的大表按块范围存 min/max 摘要(体积极小、维护轻),宽范围查询按摘要跳过块;随机键/点查选择性差会退化全扫,与 B 树可共存互补 ✓ 正确答案 C BRIN 支持唯一约束 D BRIN 元数据与表大小成正比很大
# 58. GIN 索引的典型应用场景? A GIN 支持唯一约束与排序 B GIN 适合范围查询 C GIN 是倒排索引,适合数组/JSONB/hstore 的包含与存在查询、tsvector 全文检索与 trigram 模糊匹配;写入经 pending list 延迟合并(fastupdate),不支持唯一与有序扫描 ✓ 正确答案 D GIN 索引维护成本与 B 树相同
# 59. INCLUDE 子句(PostgreSQL 11+)的用途? A INCLUDE 列参与索引排序 B INCLUDE 列不参与排序/搜索、只附加在叶子用于覆盖查询(Index Only Scan 免回表),可包含大字段且索引更小维护成本低,但 INCLUDE 列不能用于 WHERE 过滤 ✓ 正确答案 C INCLUDE 与普通组合索引完全等价 D INCLUDE 列可以作查询条件
# 60. MySQL 的 FORCE INDEX、USE INDEX、IGNORE INDEX 的语义差异? A USE INDEX 是建议(优化器可忽略)、FORCE INDEX 强制(除非索引不可用)、IGNORE INDEX 排除候选;提示用于统计缺陷的临时干预,长期依赖会在数据分布变化后失效 ✓ 正确答案 B USE INDEX 强制使用指定索引 C FORCE INDEX 一定最优 D 索引提示可跨库移植
# 61. PostgreSQL 中哈希索引为何曾被标记为“实验性”? A 哈希索引从早期就崩溃安全 B 哈希索引现在仍不支持唯一 C 哈希索引支持范围查询 D 哈希索引曾因不写 WAL(崩溃后损坏需 REINDEX)、功能不完整而被标为实验性,PostgreSQL 10 重写后支持 WAL/UNIQUE/并行构建,现生产可用但仅适合等值查询 ✓ 正确答案
# 62. PostgreSQL 中如何查看表的索引信息?\d t 的输出包含哪些内容? A \d t 显示索引段(名称、UNIQUE/PRIMARY、USING 方法、键列、WHERE/表达式),pg_indexes 的 indexdef 给出完整 CREATE INDEX,pg_stat_user_indexes 提供使用统计 ✓ 正确答案 B \d 只显示索引名 C pg_indexes 不含索引定义 D 主键索引不会在 \d 中显示
# 63. 唯一索引的 NULL 处理(PG 多 NULL、Oracle 多 NULL、SQL Server 单 NULL)? A 所有数据库唯一索引都只允许一个 NULL B PostgreSQL/Oracle/MySQL 唯一索引允许多个 NULL(标准语义),SQL Server 唯一索引默认单 NULL(唯一约束多 NULL);"单 NULL"需求用 COALESCE 表达式唯一索引或生成列实现,"多 NULL"用过滤索引 ✓ 正确答案 C SQL Server 唯一约束也是单 NULL D NULL 不参与唯一性比较
# 64. 索引的 TABLESPACE 选项如何迁移? A 索引可独立放表空间(存储分层),ALTER INDEX ... SET TABLESPACE 移动索引(需 ACCESS EXCLUSIVE 锁、目标空间充足);无阻塞迁移用 CONCURRENTLY 建新索引后删旧 ✓ 正确答案 B ALTER INDEX SET TABLESPACE 不锁表 C MySQL 索引可独立移动表空间 D 索引必须与表同表空间
# 65. 索引的 WHERE 子句与部分索引的关系? A 部分索引可用于任意查询 B 部分索引与普通索引不能共存 C 查询条件超出索引条件也能用部分索引 D 部分索引只含满足 WHERE 条件的行,查询需"谓词蕴含索引条件"才被使用(如 status='PENDING' 且查询含该条件),优化器做蕴含判定,EXPLAIN 验证 ✓ 正确答案
# 66. 索引的并行创建(PARALLEL)参数? A 并行建索引用多 CPU 扫描排序构建(SQL Server MAXDOP、MySQL 8.0.14 innodb_parallel_build_index、Oracle PARALLEL),PostgreSQL 不支持(仅 CONCURRENTLY 在线单进程);需权衡 CPU/临时空间竞争 ✓ 正确答案 B PostgreSQL 支持并行建索引 C MySQL 8.0 默认开启并行建索引 D 并行度越高一定越快
# 67. PostgreSQL 的 search_path 机制,未限定对象名时如何按顺序在多个 schema 中查找? A search_path 不影响对象解析 B 未限定对象名按 search_path 从左到右取第一个命中(默认 "$user", public),pg_catalog/pg_temp 隐式优先;它同时决定未限定建表的落点,可用 SET/ALTER ROLE 修改 ✓ 正确答案 C 查找会合并所有 schema 的结果 D pg_catalog 需要显式写入 search_path
# 68. search_path 的安全风险,恶意用户创建同名的函数/视图污染搜索路径的攻击(search_path 攻击)。 A search_path 攻击只影响视图不影响函数 B 函数体内的解析不受 search_path 影响 C public 的 CREATE 权限无安全影响 D 未限定名按 search_path 解析,恶意用户可在可写 schema(尤其 public)创建同名函数/表劫持引用,SECURITY DEFINER 函数内解析被操纵可提权;防护是收紧 public、函数内固定 search_path、全限定引用 ✓ 正确答案
# 69. 如何通过 pg_db_role_setting 设置默认 search_path?如何通过 ALTER ROLE/USER 设置? A ALTER ROLE SET 立即影响现有会话 B ALTER ROLE/DATABASE SET search_path 写入 pg_db_role_setting(setdatabase/setrole/setconfig),新会话按"库<角色<角色+库<会话 SET"的优先级加载生效 ✓ 正确答案 C pg_db_role_setting 不含 GUC 内容 D 角色级设置优先级高于会话内 SET
# 70. MySQL 的数据库(Database)与 PostgreSQL 的 Schema 切换语法差异?USE db vs SET search_path? A 两者的解析机制完全相同 B search_path 只能包含一个 schema C MySQL 的 USE 设置单一默认库(跨库需全限定),PostgreSQL 的 search_path 是多个 schema 的有序列表(按序查找回退);两者都决定未限定名解析与建表落点 ✓ 正确答案 D USE 可以设置多个默认库
# 71. Oracle 的同义词(Synonym)与 PostgreSQL 的 search_path 对比? A 两者机制完全相同 B search_path 可以给对象起别名 C Oracle 同义词是"任意名→对象"的别名(私有/公共、解析链、解耦改名),PostgreSQL 无同义词、用 search_path 的同名目录顺序查找(不同名解耦用视图转发),机制与命名自由度不同 ✓ 正确答案 D 同义词不参与对象解析
# 72. search_path 在函数体内的可见性? A 函数体内总是按定义者的 search_path 解析 B 动态 SQL 中的解析与 search_path 无关 C PL/pgSQL 函数体内未限定名按执行时(调用者)的 search_path 动态解析,故 SECURITY DEFINER 函数必须用函数级 SET search_path 固定;SQL 函数/视图在创建时绑定对象 OID ✓ 正确答案 D 调用者无法影响函数内解析
# 73. 公共 schema(public)的安全最佳实践? A public 中创建对象无风险 B 15 后 public 仍允许任意用户创建对象 C PostgreSQL 15 前 PUBLIC 默认对 public 有 CREATE 权限(search_path 攻击温床),加固要点是 REVOKE CREATE、业务对象移入专属 schema、收紧 search_path 并审计对象 ✓ 正确答案 D public 无法回收权限
# 74. 如何为函数固定 search_path?SET search_path FROM CURRENT? A SET search_path FROM CURRENT 表示每次执行时取当前路径 B 函数内的解析不受函数级 SET 影响 C 函数级 SET search_path 固定函数体内对象解析(防 search_path 攻击),SET search_path FROM CURRENT 在创建函数时快照当前会话路径(等价显式字面量),安全实践应含 pg_catalog ✓ 正确答案 D RESET search_path 无法用于函数
# 75. DROP TRIGGER 的语法与权限要求? A PostgreSQL 的 DROP TRIGGER 需指定表名且需表 owner 权限(IF EXISTS 幂等、触发器函数独立保留),MySQL 按库内触发器名删除(需 TRIGGER 权限) ✓ 正确答案 B PostgreSQL 中删除触发器会同时删除触发器函数 C 任何用户都可以删除触发器 D 触发器删除不可回滚
# 76. 事件调度(Event Scheduler)能否替代业务侧的 Cron 作业? A 事件调度可以完全替代 Cron B pg_cron 可以调用外部 HTTP 服务 C 库内调度(EVENT/pg_cron/Agent Job)适合数据库内维护任务(清理、刷新物化视图),跨系统调用、复杂编排、高可用与可观测性需求应用任务平台,库内任务需自建日志与告警 ✓ 正确答案 D 库内调度随实例故障也能自动补跑
# 77. 序列的回滚(setval、ALTER SEQUENCE RESTART)在数据修复时的使用风险? A 回拨序列没有风险 B setval 只在当前会话生效 C setval/RESTART 用于修复时"只前移到 MAX(id)"是安全的,回拨可能生成重复主键、破坏单调性且与并发 nextval 竞态;必须回拨时应在停写窗口并验证 ✓ 正确答案 D 回拨后并发插入不会冲突
# 78. 触发器与约束检查的执行顺序(BEFORE 触发器 vs CHECK 约束、DEFERRABLE 约束的推迟时机) A CHECK 约束先于 BEFORE 触发器 B 顺序为 BEFORE 触发器 → 行写入(NOT NULL/CHECK/唯一在写入时检查、外键在语句结束时检查)→ AFTER 触发器(BEFORE 可改 NEW、行级约束检查修改后的值);DEFERRABLE 约束推迟到事务提交检查(晚于 AFTER 触发器,延迟窗口内可暂时违反) ✓ 正确答案 C BEFORE 触发器可以绕过约束 D 延迟约束在语句结束检查
# 79. PostgreSQL 的 B-tree/GiST/GIN/BRIN 索引类型分别适合什么查询(精确/范围/全文/空间/时序) A 所有查询都适合 B-tree B B-tree 适合等值/范围/排序/唯一,GIN 适合数组/JSONB 元素与全文,GiST 适合空间/范围重叠/近邻,BRIN 适合物理有序大表的范围扫描,按查询形态组合选用 ✓ 正确答案 C GIN 支持唯一约束 D BRIN 适合点查
# 80. ALTER SEQUENCE 的常用子句有哪些? A START WITH 会立即改变当前值 B ALTER SEQUENCE 只需 USAGE 权限 C CACHE 修改立即影响已预分配的值 D ALTER SEQUENCE 可改 INCREMENT/CACHE/CYCLE/OWNED BY 等,RESTART 立即重置当前值而 START WITH 只改默认起点,RESTART 常用于修复对齐 ✓ 正确答案
# 81. CREATE SEQUENCE seq START 1 INCREMENT 1 的完整语法含义? A START 1 表示第一次调用返回 0 B CACHE 默认 100 C CREATE SEQUENCE seq START 1 INCREMENT 1 创建步长 1、起点 1 的计数器(nextval 返回 1,2,3...),默认 NO CYCLE 到上限报错、CACHE 1 每次持久化,可用步长错开多实例 ✓ 正确答案 D 序列默认会循环
# 82. 如何查询当前 schema 的所有序列? A information_schema.sequences 包含 last_value B 序列无法按 schema 查询 C 可用 \ds、information_schema.sequences(标准)、pg_class relkind='S'(权威)或 pg_sequences(参数+last_value 最实用)查询当前 schema 的序列,注意过滤系统 schema ✓ 正确答案 D pg_sequences 不含增量参数
# 83. 序列的 cache 参数对性能的影响如何? A CACHE 只影响空洞不影响性能 B CACHE n 内存预分配 n 个值(段边界才写 WAL/持久化),高并发 nextval 吞吐大幅提升;代价是崩溃丢失未用段产生空洞、取值跳变,并发敏感场景调大、需严格连续场景用小值 ✓ 正确答案 C CACHE 1 并发性能最好 D CACHE 值越大段边界写越多
# 84. 生成列的两种类型(VIRTUAL vs STORED)各自的存储成本? A VIRTUAL 占行存储 B VIRTUAL 行内不存储(查询时计算、写入快、可索引),STORED 写入时物化(占存储、读快、可作分区键/外键);按表达式成本与读写频率选择,PostgreSQL 仅支持 STORED ✓ 正确答案 C STORED 不占存储 D VIRTUAL 不能建索引
# 85. MONEY 类型的局限(精度、地区格式化)? A MONEY 精度任意可配 B MONEY 固定精度且输入输出依赖 lc_monetary 地区格式化(跨 locale 不稳定),金融场景应使用 NUMERIC/DECIMAL(任意精度、语义稳定、跨库一致),MONEY 仅适合单 locale 轻量展示 ✓ 正确答案 C MONEY 不受 locale 影响 D MONEY 与 NUMERIC 完全等价
# 86. 枚举类型能否新增值?ALTER TYPE ADD VALUE 的语法? A 枚举值可以插入到任意位置 B 枚举值可以随时删除 C ALTER TYPE ... ADD VALUE 只能追加到末尾(排序=定义序),不能删除/改名(需重建类型),PG 12+ 支持事务内使用;MySQL 用 ALTER TABLE MODIFY 重建表,灵活值列表应用字典表 ✓ 正确答案 D ADD VALUE 无需提交即可使用
# 87. DROP INDEX 与 ALTER TABLE DROP INDEX 的差异? A 所有数据库都支持 ALTER TABLE DROP INDEX B PostgreSQL 的 DROP INDEX 可删除主键索引 C PostgreSQL 仅 DROP INDEX(约束伴随索引需 DROP CONSTRAINT,索引与约束分离),MySQL 的 DROP INDEX/ALTER TABLE DROP INDEX 等价(约束即索引),SQL Server 需带表名 ✓ 正确答案 D 删除索引不影响外键检查
# 88. 临时 schema(pg_temp_*)在 search_path 中的优先级,同名临时对象如何覆盖永久对象? A 临时对象与永久对象互不影响 B 会话的 pg_temp schema 隐式优先于 pg_catalog 与 search_path:同名临时表遮蔽永久表(需全限定名访问),函数解析同样受影响,残留临时表是常见 bug 来源 ✓ 正确答案 C pg_temp 只在显式写入 search_path 时生效 D 其他会话可以解析到本会话的临时表
# 89. current_schema()、current_schemas(boolean) 的语义差异? A current_schema() 返回 search_path 中第一个存在的 schema(未限定对象落点),current_schemas(include_implicit) 返回完整路径数组(true 时含 pg_catalog/pg_temp 隐式项),用于调试解析路径 ✓ 正确答案 B 两者返回相同内容 C current_schemas(false) 包含 pg_catalog D current_schema() 返回所有 schema
# 90. SET search_path TO public, app 的语义? A 列表顺序不影响解析 B 该设置会立即影响已解析的语句 C pg_catalog 会被 public 覆盖 D 该设置使 public 优先(未限定名先查 public 再查 app、建表落点 public),与默认 "$user", public 相比移除了 $user 并加入 app,顺序相反则 app 优先 ✓ 正确答案
# 91. CREATE TABLE 未限定模式名时默认创建在哪个 schema? A 未限定建表总是落在 public B 未限定建表落在 search_path 第一个存在的 schema(默认 "$user" 命中则用户同名 schema、否则 public);落点随路径配置变化,跨环境可能不一致,生产应显式限定或固定 search_path ✓ 正确答案 C 落点与 search_path 无关 D CREATE TEMP TABLE 也受该规则影响
# 92. 为什么生产环境不推荐使用 public schema? A public 有权限宽松(15 前 PUBLIC 可 CREATE)与 search_path 攻击风险,多应用共享时对象混乱、审计困难;实践是按应用建专属 schema、固定 search_path、模板库预置 ✓ 正确答案 B public 没有任何风险 C 所有表都应在 public 共享 D 15 后 public 完全无风险
# 93. 什么是谓词触发器(Predicate Trigger)? A 谓词触发器指"满足谓词条件才触发"的触发器:PostgreSQL/Oracle 用 WHEN 子句实现(条件不满足不调用函数),与事件触发器(DDL 事件)及无条件触发器相对 ✓ 正确答案 B 谓词触发器是响应 DDL 事件的触发器 C SQL Server 有独立的谓词触发器类型 D 谓词触发器与普通触发器完全相同
# 94. MySQL 中如何为列设置自增? A AUTO_INCREMENT 列必须是索引列(通常主键),省略该列自动分配、显式插入后计数器跳变,LAST_INSERT_ID() 会话级取回,重置不能低于 max+1,8.0 计数器持久化 ✓ 正确答案 B 自增列不要求是索引列 C LAST_INSERT_ID() 是全局的 D 自增可回拨到任意值
# 95. 雪花 ID 的 64 位结构如何划分? A 经典雪花 ID = 1 位符号 + 41 位毫秒时间戳(约 69 年)+ 10 位节点(1024 个)+ 12 位序列(每毫秒 4096),趋势递增且去中心;时钟回拨会导致重复 ID 需专门处理 ✓ 正确答案 B 雪花 ID 没有时间信息 C 节点位有 32 位 D 雪花 ID 全局严格单调递增
# 96. CREATE INDEX idx_name ON t(col) 的基本语法? A 索引名在表内唯一即可 B CREATE [UNIQUE] INDEX 名 ON t (col) 默认建 B 树非唯一索引,可扩展 UNIQUE/USING 方法/复合列/表达式/部分条件/INCLUDE/CONCURRENTLY 等选项,索引随表删除、写入需维护 ✓ 正确答案 C 索引创建后需修改代码才能生效 D 默认索引方法是 GIN
# 97. 什么是倒排索引(Inverted Index)? A 倒排索引以"词项/值 → 包含它的行列表"反向组织,适合文本全文、数组元素、JSONB 键值的包含/存在查询(PostgreSQL GIN、Lucene 实现),不适合范围与排序 ✓ 正确答案 B 倒排索引适合范围查询 C 倒排索引与 B 树结构相同 D 倒排索引无法用于全文检索
# 98. 部分索引(Partial Index)与表达式索引的适用场景与维护成本 A 部分索引只对满足 WHERE 条件的行维护(判断+子集量),表达式索引每行"计算+维护";两者可组合为"子集内表达式索引"(体积与维护最优),配合使用统计清理无用索引 ✓ 正确答案 B 表达式索引只维护子集行 C 部分索引维护成本与全量相同 D 表达式索引不增加写入开销