本页面介绍如何创建和管理 Spanner 视图。如需详细了解 Spanner 视图,请参阅关于视图。
权限
如需创建、授予和撤消对视图的访问权限,您必须拥有 spanner.database.updateDdl
权限。
创建视图
如需创建视图,请使用 DDL 语句 CREATE VIEW
命名视图,并提供定义视图的查询。此语句有两种形式:
CREATE VIEW
用于定义当前数据库中的新视图。如果名为view_name
的视图已存在,则CREATE VIEW
语句将失败。CREATE OR REPLACE VIEW
用于定义当前数据库中的新视图。如果已经存在名为view_name
的视图,则其定义会被替换。
CREATE VIEW 语句的语法如下:
{CREATE | CREATE OR REPLACE } VIEW view_name SQL SECURITY { INVOKER | DEFINER } AS query
由于视图是虚拟表,因此您指定的 query
必须提供该虚拟表中的所有列的名称。
此外,Spanner 还会使用严格名称解析来检查您指定的 query
,这意味着查询中使用的所有架构对象名称都必须经过限定,从而能够明确标识单个架构对象。例如,Singers
表的 SingerId
列后面的示例必须限定为 Singers.SingerId
。
您必须在 CREATE VIEW
或 CREATE OR REPLACE VIEW
语句中将 SQL SECURITY
指定为 INVOKER
或 DEFINER
。如需详细了解这两种安全类型之间的区别,请参阅关于视图。
例如,假设 Singers
表的定义如下所示:
GoogleSQL
CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX) ) PRIMARY KEY (SingerId);
PostgreSQL
CREATE TABLE Singers ( SingerId BIGINT PRIMARY KEY, FirstName VARCHAR(1024), LastName VARCHAR(1024), SingerInfo BYTEA );
您可以定义具有调用方权限的 SingerNames
视图,如下所示:
CREATE VIEW SingerNames SQL SECURITY INVOKER AS SELECT Singers.SingerId AS SingerId, Singers.FirstName || ' ' || Singers.LastName AS Name FROM Singers;
在查询中使用 SingerNames
视图时创建的虚拟表包含 SingerId
和 Name
列。
虽然此 SingerNames
视图的定义有效,但没有遵循数据类型转换的最佳做法,该最佳做法旨在确保架构更改的稳定性,如下一部分所述。
创建视图时的最佳做法
要尽量减少更新视图定义的需求,请在定义视图的查询中显式类型转换所有表列的数据类型。执行此操作后,视图的定义在列类型架构更改时可保持有效。
例如,如果更改 Singers
表中某一列的数据类型,以下 SingerNames
视图定义可能会失效。
CREATE VIEW SingerNames SQL SECURITY INVOKER AS SELECT Singers.SingerId AS SingerId, Singers.FirstName || ' ' || Singers.LastName AS Name FROM Singers;
您可以将列显式转换为所需的数据类型,以避免视图失效,如下所示:
GoogleSQL
CREATE OR REPLACE VIEW SingerNames SQL SECURITY INVOKER AS SELECT CAST(Singers.SingerId AS INT64) AS SingerId, CAST(Singers.FirstName AS STRING) || " " || CAST(Singers.LastName AS STRING) AS Name FROM Singers;
PostgreSQL
CREATE OR REPLACE VIEW SingerNames SQL SECURITY INVOKER AS SELECT CAST(Singers.SingerId AS bigint) AS SingerId, CAST(Singers.FirstName AS varchar) || ' ' || CAST(Singers.LastName AS varchar) AS Name FROM Singers;
授予和撤消对视图的访问权限
作为精细的访问权限控制用户,您必须拥有视图的 SELECT
权限。如需向数据库角色授予对视图的 SELECT
权限,请执行以下操作:
GoogleSQL
GRANT SELECT ON VIEW SingerNames TO ROLE Analyst;
PostgreSQL
GRANT SELECT ON TABLE SingerNames TO Analyst;
如需从数据库角色撤消视图的 SELECT
权限,请执行以下操作:
GoogleSQL
REVOKE SELECT ON VIEW SingerNames FROM ROLE Analyst;
PostgreSQL
REVOKE SELECT ON TABLE SingerNames FROM Analyst;
查询视图
查询调用者权限或定义者权限视图的方式相同。但是,Spanner 不一定需要对照调用查询的主账号的数据库角色来检查视图中引用的架构对象,具体取决于视图的安全类型。
查询调用方的权限视图
如果某个视图具有调用方的权限,用户必须拥有该视图的所有底层架构对象的相关权限,才能查询该视图。
例如,如果数据库角色有权访问 SingerNames
视图引用的所有对象,则可以查询 SingerNames
视图:
SELECT COUNT(SingerID) as SingerCount FROM SingerNames;
查询定义者的权限视图
如果某个视图具有定义者的权限,只要您为所需角色授予了针对该视图的 SELECT
权限,用户就无需具备底层对象的权限即可查询该视图。
在以下示例中,具有“分析师”数据库角色的用户想要查询 SingerNames
视图。但是,系统会拒绝用户访问,因为 SingerNames
是调用者的权限视图,而“分析师”角色无权访问所有底层对象。在这种情况下,如果您决定向分析人员提供对该视图的访问权限,但不想为其提供对 Singers
表的访问权限,则可以将该视图的安全类型替换为定义者的权限。替换视图的安全类型后,向“分析师”角色授予对视图的访问权限。现在,即使该用户无权访问 Singers
表,也可以查询 SingerNames
视图。
SELECT COUNT(SingerID) as SingerCount FROM SingerNames;
替换视图
您可以使用 CREATE OR REPLACE VIEW
语句更改视图定义或视图安全类型,从而替换视图。
替换视图类似于丢弃并重新创建视图。为初始视图授予的任何访问权限都必须在替换视图后重新授予。
要将调用者的权限视图替换为定义者的权限视图,请执行以下操作:
CREATE OR REPLACE VIEW SingerNames SQL SECURITY DEFINER AS SELECT Singers.SingerId AS SingerId, Singers.FirstName || ' ' || Singers.LastName AS Name FROM Singers;
删除视图
视图被删除后,具有该视图权限的数据库角色将不再具有访问权限。如需删除视图,请使用 DROP VIEW
语句。
DROP VIEW SingerNames;
获取视图相关信息
您可以通过查询数据库的 INFORMATION_SCHEMA
架构中的表来获取有关数据库中视图的信息。
INFORMATION_SCHEMA.TABLES
表提供所有已定义视图的名称。INFORMATION_SCHEMA.VIEWS
表提供了所有已定义视图的名称、视图定义、安全类型和查询文本。对视图具有SELECT
权限的 FGAC 用户可以从INFORMATION_SCHEMA.VIEWS
表获取有关该视图的信息。如果其他 FGAC 用户没有视图的SELECT
权限,则需要spanner_info_reader
角色。
如需查看名为 ProductSoldLastWeek
的视图的视图定义和安全类型,请使用以下代码:
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'ProductSoldLastWeek';