视图记在 sqlite_master 里,type 是 view,和表混在同一张清单里,靠 type 区分。
sql 那一列原样存着建视图时写的那句话;
MySQL 那边是 SHOW CREATE VIEW,还能查 information_schema.views。
PRAGMA table_info 对视图也能用,但 pk、dflt_value 全是 0——
视图没有主键、没有默认值,别拿它当表结构用。
上一篇建视图,这一篇学「查视图」——查的是「有哪些视图」和「视图怎么定义的」。 这件事在维护时比建视图更常用:接手一个老库,第一件事就是列出所有视图看一遍, 因为视图里往往藏着最复杂的业务逻辑。
一、视图记在 sqlite_master 里,type 是 view
where type in ('table', 'view') 把表和视图一起列出来,
靠 type 区分。 Demo 里六张表加一个视图,一共七行。
所以「这个库里有哪些视图」就是加一句 where type = 'view'。
对使用者来说,视图和表在 select 里长得一样,只有查元数据时才需要区分。
二、看视图的定义:就是那句 SQL
sql 那一列原样存着建视图时写的那句话。 拿它出来看,就知道这个视图到底在算什么。
MySQL 那边是 SHOW CREATE VIEW 视图名,给的信息更多(字符集、检查选项、定义者)。
也能查 information_schema.views,
有 VIEW_DEFINITION、CHECK_OPTION、IS_UPDATABLE 这些列。
最后那个 IS_UPDATABLE 特别实用:
它直接告诉你「这个视图能不能写」,不用自己去判断有没有聚合、union。
本沙箱没有这个视图,只能靠读定义自己看。
三、看视图的列:PRAGMA 也能用
视图的列信息也能查出来,但注意 pk 和 dflt_value 全是 0——视图没有主键、没有默认值,
它只是「查询结果的形状」。
notnull 也不可靠:
视图里一列是否非空,取决于查询怎么写,而不是基表的约束。
所以别拿视图的 PRAGMA 当表结构用。
真正要看的还是基表的 PRAGMA。 视图的 PRAGMA 只用来确认「列名对不对、列数对不对」,
这两个信息它是准的。
四、视图的依赖:改基表前先看谁在用它
拿视图定义的文本去 like '%students%',能找到引用某张表的视图。
这是土办法,但比「什么都不查就改」强得多。
它很粗糙:改个表名、加个空格就匹配不上;
表名是另一个表名的子串时还会误报(比如 order 和 order_detail)。
真 MySQL 上可以查 information_schema.view_table_usage,
那是专门记录「视图用了哪些表」的,精确得多。
本沙箱只能靠文本匹配,所以要记得:视图依赖是隐式的,删表前必须人工确认。
五、动手 Demo:列出表和视图、看定义、看列、找依赖
Demo 四段:把表和视图一起列出来、取视图的定义、用 PRAGMA 看视图的列,
最后用 like 找「谁引用了 students」。
第四段那个 like 是这一篇最实用的技巧,虽然粗糙,但改表之前花十秒跑一遍,能挡掉很多事故。
import _q46 as Q
c = Q.con()
c.execute("CREATE VIEW v_boy AS SELECT id, name, height "
"FROM students WHERE gender = '男'")
# 表和视图混在一张清单里,靠 type 区分
Q.show(c, "SELECT type, name FROM sqlite_master "
"WHERE type IN ('table', 'view') ORDER BY type, name")
# 视图的定义就是那句 SQL
Q.show(c, "SELECT sql FROM sqlite_master WHERE name = 'v_boy'")
# 视图的列信息
Q.show(c, "PRAGMA table_info(v_boy)")
# 谁在引用 students:拿定义文本去 like
Q.show(c, "SELECT name, sql FROM sqlite_master WHERE type = 'view' "
"AND sql LIKE '%students%'")
实跑输出:
--------------------------------------------------------------------
第五十九课:查看视图——它也是系统表里的一条记录
--------------------------------------------------------------------
视图记在 sqlite_master 里,type 是 view
SQL> SELECT type, name FROM sqlite_master WHERE type IN ('table', 'view') ORDER BY type, name
type name
-----------------------
table classes
table goods
table order_detail
table orders
table scores
table students
view v_boy
(7 行)
**表和视图混在一张清单里,靠 `type` 区分。**
**所以「这个库里有哪些视图」就是加一句 `where type = 'view'`。**
**注意六张样例表都在,但它们和视图平级**——
**对使用者来说,视图和表在 `select` 里长得一样,只有查元数据时才需要区分。**
看视图的定义:就是那句 SQL
SQL> SELECT sql FROM sqlite_master WHERE name = 'v_boy'
CREATE VIEW v_boy AS SELECT id, name, height FROM students WHERE gender = '男'
**`sql` 那一列原样存着建视图时写的那句话。** **MySQL 那边是 `SHOW CREATE VIEW 视图名`**,
给的信息更多(字符集、检查选项、定义者)。
**`information_schema.views` 也能查**,
**有 `VIEW_DEFINITION`、`CHECK_OPTION`、`IS_UPDATABLE` 这些列**——
**最后那个能直接告诉你「这个视图能不能写」,很实用。**
看视图的列:PRAGMA 也能用
SQL> PRAGMA table_info(v_boy)
cid name type notnull dflt_value pk
---------------------------------------------------------------------
0 id INTEGER 0 NULL 0
1 name TEXT 0 NULL 0
2 height REAL 0 NULL 0
(3 行)
**视图的列信息也能查出来**,
但**注意 `pk` 和 `dflt_value` 全是 0**——**视图没有主键、没有默认值**,它只是「查询结果的形状」。
**`notnull` 也不可靠**:
**视图里一列是否非空,取决于查询怎么写,而不是基表的约束。**
**所以别拿视图的 `PRAGMA` 当表结构用。**
视图的依赖:改基表前先看谁在用它
SQL> SELECT name, sql FROM sqlite_master WHERE type = 'view' AND sql LIKE '%students%'
name sql
-----------------------------------------------------------------------------------------
v_boy CREATE VIEW v_boy AS SELECT id, name, height FROM students WHERE gender = '男'
(1 行)
**这是找「谁引用了某张表」的土办法**:拿视图定义的文本去 `like` 一下。
**它很粗糙**(**改个表名、加个空格就匹配不上**),
**但比「什么都不查就改」强得多。** **真 MySQL 上可以查 `information_schema.view_table_usage`**,
**那是专门记录「视图用了哪些表」的。**
**本沙箱只能靠文本匹配,所以要记得:视图依赖是隐式的,删表前必须人工确认。**
第一段七行:六张表加一个 v_boy,type 列区分。
第二段给出完整的建视图语句,一字不差。
第三段 PRAGMA 三行,pk 和 dflt_value 全是 0。
第四段筛出 v_boy——它是唯一引用 students 的视图。
30 秒实验
- 怎么列出这个库里所有的视图?
- 视图的
PRAGMA table_info里,pk列为什么永远是 0? - 要改基表结构,怎么先查出「哪些视图会受影响」?
常见误区
- 拿视图的
PRAGMA当表结构用。pk、dflt_value、notnull都不可靠,要看结构得看基表。 - 以为改了视图就完事,不管谁在用。 视图藏起来的复杂度,改错了有一堆报表跟着崩。
- 用
like '%order%'找依赖。 会连带匹配order_detail,误报一堆, 该把表名带上下划线或者用元数据表查。
自测三问(点开对答案)
1. 怎么看出一个库里有哪些视图? —— 查 `sqlite_master` 加 `where type = 'view'`。 MySQL 用 `SHOW FULL TABLES WHERE Table_type = 'VIEW'`。 2. 视图的定义存在哪一列? —— `sqlite_master` 的 `sql` 列,原样存着建视图时写的那句语句。MySQL 用 `SHOW CREATE VIEW`。 3. 为什么视图的 `PRAGMA` 里 `pk` 永远是 0? —— 视图不是表,没有主键和默认值,它只是查询结果的形状。会看了,接下来是「改」。下一篇 11.3 修改视图——两条路,这里都走不通。
- ☐ (本篇完,下一篇 11.3 修改视图)