Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions docs/docs/game/create-view-2025.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
title: 2025 初赛 create-view 题目
---

# 视图更新规则说明

本规则用于判断不同类型的视图是否支持 `INSERT``UPDATE``DELETE` 操作。
核心原则:**只有当数据库能明确地将操作映射回基表的某一行时,才允许更新。**

> ⚠️ 说明:
> 1. 即使视图为空,不可删除的操作也会执行失败。
> 2. 本题目暂不考虑 `GROUP BY``ORDER BY``HAVING``LIMIT` 等子句。
> 3. 嵌套视图的可更新性依赖其源视图;本题目暂不考虑嵌套视图更新。
---

## 视图类型与操作权限对照表

| 视图类型 |       定义示例       | INSERT(插入) | UPDATE(更新) | DELETE(删除) | 详细说明 |
|----------|-----------|----------------|----------------|----------------|-----------|
| 单表视图 | `CREATE VIEW v AS SELECT * FROM t;` | ✅ 允许 | ✅ 允许 | ✅ 允许 | 基于单个表的完整列视图,完全可更新 |
| 单表视图(部分列) | `CREATE VIEW v(id, age) AS SELECT id, age FROM t;` | ✅ 允许(仅指定列)<br>❌ 不允许(全列且未覆盖) | ✅ 允许(仅修改包含的列)<br>❌ 不允许(修改非包含列) | ✅ 允许 | 插入时,其他列为 `NULL`;若缺失的列为 `NOT NULL` 且无默认值,则插入失败 |
| 多表视图 | `CREATE VIEW v AS SELECT t1.id, t2.age FROM t1, t2;` | ⚠️ 部分允许<br>✅ 若只影响一个基表的列<br>❌ 若涉及多个基表 | ⚠️ 部分允许<br>✅ 若只更新来自同一基表的列<br>❌ 若跨多个基表更新 | ❌ 不允许 | 插入或更新只能作用于单一基表对应的字段。<br>例如:<code>INSERT INTO v(id)</code> 可能允许(仅 t1),但 <code>INSERT INTO v VALUES(...)</code> 同时写两表则禁止 |
| 单表视图(含表达式) | `CREATE VIEW v AS SELECT id, id + age AS data FROM t;` | ✅ 允许(仅插入基础列)<br>❌ 不允许(插入表达式列) | ✅ 允许(仅更新基础列)<br>❌ 不允许(更新表达式列) | ✅ 允许 | 表达式列(如 <code>id + age</code>)是计算值,不能写入;<br>只能对原始列(如 <code>id</code>, <code>age</code>)进行插入或更新 |
| 单表视图(含聚合) | `CREATE VIEW v AS SELECT COUNT(*) AS cnt FROM t;` | ❌ 不允许 | ❌ 不允许 | ❌ 不允许 | 聚合结果无法映射回原表的具体行;<br>此类视图为只读 |
| 嵌套视图 | `CREATE VIEW v1 AS SELECT id FROM v2;` | ✅ 允许(当 v2 可插入)<br>❌ 不允许(当 v2 不可插入) | ✅ 允许(当 v2 可更新)<br>❌ 不允许(当 v2 不可更新) | ✅ 允许(当 v2 可删除)<br>❌ 不允许(当 v2 不可删除) | 嵌套视图的操作权限完全依赖源视图。<br>若源视图 <code>v2</code> 支持某操作,则 <code>v1</code> 可能支持;否则一律禁止 |

---

## 关键术语解释

- **基表(Base Table)**:视图所基于的真实数据表。
- **可更新视图(Updatable View)**:指对该视图的 DML 操作能够成功传递到基表并生效。
- **表达式列**:由计算生成的列,如 `price * qty``UPPER(name)``col + 1` 等。
- **聚合列**:使用聚合函数生成的列,如 `COUNT(*)``SUM(amount)``AVG(score)` 等。

---

## 判断流程建议

面对任意视图定义,请按以下顺序判断其可更新性:

1. **看来源**:是单表还是多表?
→ 多表 → 插入/删除通常 ❌,更新需谨慎。

2. **看列**:是否有表达式或聚合函数?
→ 有表达式 → 表达式列 ❌ 不可更新
→ 有聚合 → 整个视图 ❌ 不可插入、不可更新、不可删除

3. **看结构**:是否只是原表的一部分列?
→ 是 → 插入时注意缺失列是否允许为 `NULL`

4. **看嵌套**:是否基于另一个视图?
→ 是 → 权限继承自源视图

5. **最终结论**
只有当操作能唯一、明确地映射回基表的一行,并且不涉及虚拟列时,才允许更新。

---

## 示例速查

| 操作语句 | 是否允许 | 原因简述 |
|---------|----------|----------|
| `INSERT INTO v(id) VALUES(1);`<br>(v 是 `SELECT id, age FROM t`|| 仅插入允许的列,其余列设为 NULL |
| `INSERT INTO v VALUES(1, 2);`<br>(v 是多表连接视图) || 涉及多个基表,无法确定插入目标 |
| `UPDATE v SET data = 10;`<br>(v 含 `id+age AS data`|| `data` 是表达式列,不可写 |
| `UPDATE v SET id = 2;`<br>(v 是单表部分列视图) || `id` 是原始列,可正常更新 |
| `DELETE FROM v;`<br>(v 是聚合视图) || 聚合视图无具体行对应,不可删 |
| `INSERT INTO v1(id) ...`<br>(v1 基于可插入的 v2) || 源视图可插入,嵌套视图也可插入 |
1 change: 1 addition & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ nav:
- game/github-introduction.md
- game/gitee-instructions.md
- game/git-introduction.md
- game/create-view-2025.md
- game/miniob-vectordb-2024.md
- game/miniob-vectordb-2025.md
- game/rag-benchmark.md
Expand Down