Skip to content

Commit a747f26

Browse files
authored
add create-view-2025.md (#609)
1 parent b7de4a7 commit a747f26

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

docs/docs/game/create-view-2025.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
title: 2025 初赛 create-view 题目
3+
---
4+
5+
# 视图更新规则说明
6+
7+
本规则用于判断不同类型的视图是否支持 `INSERT``UPDATE``DELETE` 操作。
8+
核心原则:**只有当数据库能明确地将操作映射回基表的某一行时,才允许更新。**
9+
10+
> ⚠️ 说明:
11+
> 1. 即使视图为空,不可删除的操作也会执行失败。
12+
> 2. 本题目暂不考虑 `GROUP BY``ORDER BY``HAVING``LIMIT` 等子句。
13+
> 3. 嵌套视图的可更新性依赖其源视图;本题目暂不考虑嵌套视图更新。
14+
15+
---
16+
17+
## 视图类型与操作权限对照表
18+
19+
| 视图类型 |       定义示例       | INSERT(插入) | UPDATE(更新) | DELETE(删除) | 详细说明 |
20+
|----------|-----------|----------------|----------------|----------------|-----------|
21+
| 单表视图 | `CREATE VIEW v AS SELECT * FROM t;` | ✅ 允许 | ✅ 允许 | ✅ 允许 | 基于单个表的完整列视图,完全可更新 |
22+
| 单表视图(部分列) | `CREATE VIEW v(id, age) AS SELECT id, age FROM t;` | ✅ 允许(仅指定列)<br>❌ 不允许(全列且未覆盖) | ✅ 允许(仅修改包含的列)<br>❌ 不允许(修改非包含列) | ✅ 允许 | 插入时,其他列为 `NULL`;若缺失的列为 `NOT NULL` 且无默认值,则插入失败 |
23+
| 多表视图 | `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> 同时写两表则禁止 |
24+
| 单表视图(含表达式) | `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>)进行插入或更新 |
25+
| 单表视图(含聚合) | `CREATE VIEW v AS SELECT COUNT(*) AS cnt FROM t;` | ❌ 不允许 | ❌ 不允许 | ❌ 不允许 | 聚合结果无法映射回原表的具体行;<br>此类视图为只读 |
26+
| 嵌套视图 | `CREATE VIEW v1 AS SELECT id FROM v2;` | ✅ 允许(当 v2 可插入)<br>❌ 不允许(当 v2 不可插入) | ✅ 允许(当 v2 可更新)<br>❌ 不允许(当 v2 不可更新) | ✅ 允许(当 v2 可删除)<br>❌ 不允许(当 v2 不可删除) | 嵌套视图的操作权限完全依赖源视图。<br>若源视图 <code>v2</code> 支持某操作,则 <code>v1</code> 可能支持;否则一律禁止 |
27+
28+
---
29+
30+
## 关键术语解释
31+
32+
- **基表(Base Table)**:视图所基于的真实数据表。
33+
- **可更新视图(Updatable View)**:指对该视图的 DML 操作能够成功传递到基表并生效。
34+
- **表达式列**:由计算生成的列,如 `price * qty``UPPER(name)``col + 1` 等。
35+
- **聚合列**:使用聚合函数生成的列,如 `COUNT(*)``SUM(amount)``AVG(score)` 等。
36+
37+
---
38+
39+
## 判断流程建议
40+
41+
面对任意视图定义,请按以下顺序判断其可更新性:
42+
43+
1. **看来源**:是单表还是多表?
44+
→ 多表 → 插入/删除通常 ❌,更新需谨慎。
45+
46+
2. **看列**:是否有表达式或聚合函数?
47+
→ 有表达式 → 表达式列 ❌ 不可更新
48+
→ 有聚合 → 整个视图 ❌ 不可插入、不可更新、不可删除
49+
50+
3. **看结构**:是否只是原表的一部分列?
51+
→ 是 → 插入时注意缺失列是否允许为 `NULL`
52+
53+
4. **看嵌套**:是否基于另一个视图?
54+
→ 是 → 权限继承自源视图
55+
56+
5. **最终结论**
57+
只有当操作能唯一、明确地映射回基表的一行,并且不涉及虚拟列时,才允许更新。
58+
59+
---
60+
61+
## 示例速查
62+
63+
| 操作语句 | 是否允许 | 原因简述 |
64+
|---------|----------|----------|
65+
| `INSERT INTO v(id) VALUES(1);`<br>(v 是 `SELECT id, age FROM t`|| 仅插入允许的列,其余列设为 NULL |
66+
| `INSERT INTO v VALUES(1, 2);`<br>(v 是多表连接视图) || 涉及多个基表,无法确定插入目标 |
67+
| `UPDATE v SET data = 10;`<br>(v 含 `id+age AS data`|| `data` 是表达式列,不可写 |
68+
| `UPDATE v SET id = 2;`<br>(v 是单表部分列视图) || `id` 是原始列,可正常更新 |
69+
| `DELETE FROM v;`<br>(v 是聚合视图) || 聚合视图无具体行对应,不可删 |
70+
| `INSERT INTO v1(id) ...`<br>(v1 基于可插入的 v2) || 源视图可插入,嵌套视图也可插入 |

docs/mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ nav:
5151
- game/github-introduction.md
5252
- game/gitee-instructions.md
5353
- game/git-introduction.md
54+
- game/create-view-2025.md
5455
- game/miniob-vectordb-2024.md
5556
- game/miniob-vectordb-2025.md
5657
- game/rag-benchmark.md

0 commit comments

Comments
 (0)