select * 在视图中会导致列结构不可控:运行时动态扩展字段引发错位、join 时列名冲突、where/limit 优化失效、嵌套视图下推失败、工具链静默映射错误。

视图定义里写 SELECT * 会让列结构变成运行时黑盒
视图不存储元数据,只存原始 SQL 文本。一旦用 SELECT * 创建,后续对源表执行 ALTER TABLE ADD COLUMN updated_at DATETIME,视图查询结果会立刻多出一列——但视图定义里根本没这行代码。下游应用若用 rs.getString(2) 按位置取值,或 BI 工具靠列名自动映射,轻则字段错位,重则直接报错 Column index out of range。
多表 JOIN 时 SELECT * 必然触发列名冲突
两个表都有 id、name、created_at?SELECT * 会让数据库当场报错:Column 'id' is ambiguous。你必须显式限定:用表别名前缀,比如 users.id AS user_id、orders.id AS order_id;含空格或特殊字符的字段(如 [E-mail Address])还得加方括号,否则解析失败。
SELECT * 让外层 WHERE 和 LIMIT 失效
视图不是函数,无法动态干预执行路径。外层加 WHERE created_at > '2026-01-01',优化器未必能把它下推到基表扫描前;加 LIMIT 10,但视图里含 ORDER BY score DESC,MySQL 可能忽略 LIMIT,PostgreSQL 可能全量排序后截断。更麻烦的是三层嵌套视图后,WHERE user_id = 123 很可能只作用于最外层结果集,根本穿不透到底层表。
工具链和 ORM 映射因 SELECT * 静默崩坏
MyBatis 的 resultMap、JPA 的 @Column、Power BI 的自动列推断,全都依赖稳定且可预测的列名与顺序。源表新增字段后,SELECT * 视图返回的列序可能变化(尤其 MySQL 中用 AFTER 调整过字段位置),导致:MyBatis 把新字段值错映射到老字段属性上;Power BI 刷新时报 “column not found”;Java 应用用 ResultSet.getObject(i) 按索引取值,拿到完全无关的数据。这类问题往往不报错,只静默错位。
最麻烦的不是写错,而是它不报错——字段加了、顺序变了、类型冲突了,数据看着都对,上线跑几天才暴露。










