用户可以将一个使用频率较高的查询语句定义为一个持久化的对象,该持久化对象称为视图,为视图提供原始数据的表称为基表。
通过查询视图代替原来的查询表,可简化SQL语句编写。
假设公司EMPLOYEE表包含所有员工个人信息,DEPARTMENT表记录所有部门信息。用户如需查询公司的所有员工个人信息及其所属部门信息(部门名称和主管名称),要求用户能清楚地知道员工个人信息、部门信息分别存储在哪张表中,并且需要了解表与表之间的关联关系,而后再执行以下对相关表的查询语句:
ini 代码解读复制代码SELECT E.ID, E.NAME, D.NAME, DM.NAME
FROM EMPLOYEE E, DEPARTMENT D, EMPLOYEE DM
WHERE E.DEPARTMENT_ID = D.ID AND D.MNGR_ID = DM.ID;Copied!
数据库管理员相较于其他用户,通常更熟悉各个表的信息、关联关系等。若数据库管理员事先为上述查询创建一个视图:
sql 代码解读复制代码CREATE OR REPLACE VIEW EMPLOYEE_INFO(EMPLOYEE_ID, EMPLOYEE_NAME, DEPARTMENT, DEPARTMENT_MANAGER)
AS SELECT E.ID, E.NAME, D.NAME, DM.NAME
FROM EMPLOYEE E, DEPARTMENT D, EMPLOYEE DM
WHERE E.DEPARTMENT_ID = D.ID AND D.MNGR_ID = DM.ID;Copied!
当用户需要查询所有员工信息时,只需执行以下对视图的查询语句即可,操作更易效率更高。
sql 代码解读复制代码SELECT * FROM EMPLOYEE_INFO;Copied!
在上述示例中,EMPLOYEE_INFO视图并不存储任何数据,其数据完全来自EMPLOYEE表和DEPARTMENT表。
视图用于代替查询,因此视图依赖查询中涉及的其他对象,包括基表、其他视图、自定义数据类型、自定义函数等。
在为某个查询语句创建视图时,需要编译该查询语句,确保该语法合法。在编译的过程中,会检测到视图所依赖的对象,默认情况下,依赖对象不存在时视图会创建失败。若创建视图时带了FORCE关键字,YashanDB将直接创建视图,不会要求视图依赖的对象已存在。
视图创建成功后,如果修改视图依赖的对象,例如增/删基表中视图所引用的列或DROP基表,将导致视图的状态无效。待再次在视图上执行DML语句时视图才会触发重编译,如果重编译检测到对应的查询语句仍然合法,视图恢复正常可用,否则将返回错误。
用户在创建视图时,数据库会在系统表中存储视图定义查询语句的原始文本、列等信息。
当SQL语句中涉及视图的查询时,数据库会先将原始SQL中的视图改写为一个子查询(该子查询即视图定义的查询语句),再解析改写后的SQL并生成执行计划。示例如下:
sql 代码解读复制代码CREATE TABLE employees(id INT, name VARCHAR(32), LEVEL INT);
CREATE VIEW exports AS SELECT * FROM employees WHERE LEVEL > 3;
SELECT * FROM exports;
SELECT exports.* FROM (SELECT id, name FROM employees WHERE LEVEL > 3) alias_exports;Copied!
如果视图依赖别的视图,那么在改写过程中,会将被依赖的视图也改写成其定义的查询语句,最终,视图的查询会被改写为查询它直接及间接依赖的基表。
改写后的SQL与原始SQL在语义上等价,但原始SQL和用户自行直接执行改写后的SQL,有以下区别:
通常视图只是用来代替原始的查询语句,并不存储任何数据,用户在查询视图时,数据库仍然要访问基表来获取原始数据,对于复杂的查询(例如多个表Join),查询时间可能很长。
物化视图与普通视图的区别是,物化视图会将查询返回的结果以表(称为物化视图的主表)的形式存储下来,将复杂的查询转化为单个表的查询,从而提高查询性能。
由于物化视图存储了数据,因此当基表的数据发生变化时,需要反向更新物化视图中的数据,这一过程称为物化视图的刷新。
用户可以根据业务对数据的变化的敏感度来选择物化视图刷新的频率。
示例场景1:银行的账户资产评级系统,需要对用户的信用等级、资产分布做出评估,并用一个物化视图来存储该结果。这个结果对数据变化的敏感度较低,不需要在用户执行每一笔交易后实时变更,可采用每天或每周定时刷新。因此用户可以将该物化视图设置为定时刷新。
示例场景2:银行的账户监管系统,需要对特殊账户的状态做实时监控,并用一个物化视图来存储该结果。由于银行需要及时响应账户挂失、销户等状态,因此,当特定操作发生后(挂失、销户等),物化视图的数据应立即刷新,因此该物化视图应设置为基表上DML提交时立即刷新。
用户也可以根据基表的数据变化规模来决定物化视图刷新的方式。
示例场景3:银行的账户资产评级系统,由于每天活跃的账户数量巨大,并且每个账户每天的交易量可能有多个,通过分析每一笔交易确定相应账户的资产状况变化情况耗时会比基于当前账户的状态对账户重新评级更大,因此该物化视图的数据适合全量刷新。
示例场景4:银行的账户监管系统,由于发生挂失、销户的账户比例非常小,如果全部刷新一遍所有账户信息,耗时可能很长,因此该物化视图更适合根据基表上账户的变更记录而增量刷新物化视图中对应的记录。
物化视图的意义如下:
序列(Sequence)是由数据库维护的一个自动生成整数序列的模式对象,通常用于为表生成主键。
例如,当新员工入职时,公司的人力资源需要登记员工信息,并为员工分配工号,那么在数据库上需要执行以下SQL语句:
sql 代码解读复制代码INSERT INTO employees(id, ...) VALUES((SELECT MAX(id) FROM employee) + 1, ...);
DECLARE
nextId INT;
BEGIN
SELECT MAX(id) INTO nextId FROM employees;
INSERT INTO employees(id, name, ...) VALUES(nextId + 1, 'Zhang San', ...);
END;
/ Copied!
以上语句,仅适用于公司人力资源部门只有专员负责登录新入职员工。
如果有一大批新员工同时入职,并且由多个人力资源专员同时登录入职时,就可能出现多个新员工分配到同一工号的问题。使用序列则可以规避该问题并简化操作:
sql 代码解读复制代码CREATE SEQUENCE seq_empl_id;
INSERT INTO employees(id, name, ...) VALUES(seq_empl_id.NEXTVAL, 'Zhang San', ...);
CREATE TABLE employees(id INT DEFAULT seq_empl_id.NEXTVAL, name VARCHAR(32), ...);
INSERT INTO employess(name, ...) VALUES('Zhang San', ...);Copied!
通过seq_emp_id.nextval获取序列seq_emp_id的下一个值,由于该值是由数据库系统自动维护,即使有多个会话同时请求,仍然可以保证每个会话获取到唯一的值。
序列具有以下特征:
在不允许循环取值的情况下,序列的主要作用是为系统提供唯一值,序列下次取值的起点会被写入系统表以持久化。如果频繁地从序列取值,会导致更新系统表的频率过高,影响性能,因此,YashanDB为序列的值提供了缓存机制。
ini 代码解读复制代码CREATE SEQUENCE seq1 CACHE 20;
CREATE SEQUENCE seq2 CACHE 10000;
CREATE SEQUENCE seq3 NOCACHE;Copied!
以上三条语句分别创建了一个缓存为20、10000、无缓存的序列。
序列的缓存会在进程内为序列缓存连续若干个尚未取到的值,当缓存内的值取尽时,数据库会更新系统表,将下次取值的起点向后按缓存大小推进,并将缓存刷新为下一批值。
同义词是用户为一个模式对象起的别名。用户可以为表、视图、存储过程、自定义函数、程序包、序列和同义词创建同义词。
同义词具有以下特点:
可以使用以下语句为table1创建一个私有同义词:
ini 代码解读复制代码CREATE SYNONYM user1.syn1 FOR user2.table1;Copied!
通过这种方式创建出的同义词syn1属于模式user1(模式名可以不指定,此时数据库将自动将当前模式补充为同义词的模式),在其他模式下使用syn1时必须显式指定user1.syn1。
可以使用以下语句为table1创建一个公共同义词:
ini 代码解读复制代码CREATE PUBLIC SYNONYM syn1 FOR user2.table1;Copied!
通过这种方式创建出的同义词属于PUBLIC模式,用户在使用syn1时,无需指定模式名。
公共同义词被广泛地用在YashanDB系统视图中。
例如,SYS模式下有USER_TABLES视图,会显示当前模式下所有表的信息。
如果用户user1想查询属于自己模式下的所有表,那么用户需要清楚地知道USER_TABLES视图属于SYS模式,并执行以下语句:
sql 代码解读复制代码SELECT * FROM SYS.USER_TABLES;Copied!
由于YashanDB在初始化数据库阶段为SYS.USER_TABLES视图创建了公共同义词,因此user1可以执行以下语句来查询属于自己模式的表:
sql 代码解读复制代码SELECT * FROM USER_TABLES;Copied!
PL对象包括自定义数据类型、自定义函数、存储过程和程序包,详情请查阅PL文档。
作者:崖山数据库系统YashanDB
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。