SQL堂上作业十
SQL VIEW(视图)
VIEW可以理解为一个虚拟存在的表,该表并不在数据库中真实存在,行和列的数据来自既有的表中,且基于这些表动态生成。
我们可以借助这些VIEW,帮助我们更好地编写SQL语句。
VIEW的创建
CREATE VIEW empvu80
AS SELECT employee_id, last_name, salary
FROM employees
WHERE department_id = 80;
基本上可以理解为,用一个SELECT语句进行数据生成
我们可以用DESCRIBE empvu80来查看这个VIEW的数据类型,数据类型基于你选出的数据的类型
SQL> describe empvu80;
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
EMPLOYEE_ID NOT NULL NUMBER(6)
LAST_NAME NOT NULL VARCHAR2(25)
SALARY NUMBER(8,2)
基于别名的创建
在上面的VIEW建立案例中,我们发现所有的名称都是基于原先所选的表的
我们可以用起别名的方法,给新建的VIEW加上别名
建视图的代码如下,可以发现所选项都加了别名
CREATE VIEW salvu50
AS SELECT employee_id ID_NUMBER, last_name NAME,
salary*12 ANN_SALARY
FROM employees
WHERE department_id = 50;
表的类型变成下图所示:
SQL> DESCRIBE salvu50;
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
ID_NUMBER NOT NULL NUMBER(6)
NAME NOT NULL VARCHAR2(25)
ANN_SALARY NUMBER
VIEW的查看
和一般的表一样,我们可以直接用查询语句进行显示
SELECT * FROM salvu50;
由于salvu50这个表,属于“视图”,是一个虚拟的表
因此,在运行上述语句前,数据库会基于视图salvu50的定义,生成出表salvu50,然后再执行FROM salvu50的语句。
输出如下:
SQL> select * from salvu50;
ID_NUMBER NAME ANN_SALARY
---------- -------------------------------------------------- ----------
120 Weiss 96000
121 Fripp 98400
122 Kaufling 94800
123 Vollman 78000
124 Mourgos 69600
125 Nayer 38400
126 Mikkilineni 32400
127 Landry 28800
128 Markle 26400
129 Bissot 39600
130 Atkinson 33600
131 Marlow 30000
132 Olson 25200
133 Mallin 39600
134 Rogers 34800
135 Gee 28800
136 Philtanker 26400
137 Ladwig 43200
138 Stiles 38400
139 Seo 32400
140 Patel 30000
141 Rajs 42000
142 Davies 37200
143 Matos 31200
144 Vargas 30000
180 Taylor 38400
181 Fleaur 37200
182 Sullivan 30000
183 Geoni 33600
184 Sarchand 50400
185 Bull 49200
186 Dellinger 40800
187 Cabrio 36000
188 Chung 45600
189 Dilly 43200
190 Gates 34800
191 Perkins 30000
192 Bell 48000
193 Everett 46800
194 McCain 38400
195 Jones 33600
196 Walsh 37200
197 Feeney 36000
198 OConnell 31200
199 Grant 31200
已选择45行。
VIEW的修改
本处的视图修改,指的是视图定义的修改,是将表的形态,存储数据的类型进行一系列的修改,而非对视图中具体数据的值进行修改
我们可以用下面的指令进行修改:
CREATE OR REPLACE VIEW empvu80
(id_number, name, sal, department_id)
AS SELECT employee_id, first_name || ' ' || last_name,
salary, department_id
FROM employees
WHERE department_id = 80;
我们查看下表的类型,发现和之前有了很大的不同
SQL> DESCRIBE empvu80
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
ID_NUMBER NOT NULL NUMBER(6)
NAME VARCHAR2(46)
SAL NUMBER(8,2)
DEPARTMENT_ID NUMBER(4)
Complex View 的建立
相比于一般的View,Complex View可以实现多个表的存储,通常配合组函数进行表的生成。
下面是一个Complex View创建的代码:
CREATE VIEW dept_sum_vu
(name, minsal, maxsal, avgsal)
AS SELECT d.department_name, MIN(e.salary),
MAX(e.salary),AVG(e.salary)
FROM employees e, departments d
WHERE e.department_id = d.department_id
GROUP BY d.department_name;
注意数据的类别,是一些函数(如xxxsal)
在View中进行DML操作
DML is an abbreviation of Data Manipulation Language.
The DML commands in Structured Query Language change the data present in the SQL database. We can easily access, store, modify, update and delete the existing records from the database using DML commands.
上面是DML的定义,懒得翻译了qwq
通常情况下,我们可以对Single View进行DML操作,其本质上是直接对表进行操作。
但在部分情况下,我们不能进行行的删除操作和添加行的操作(比如包含组函数,去重函数等)。
视图的只读标记
我们可以添加一个WITH READ ONLY的标签来禁用某张表的DML操作。代码如下:
CREATE OR REPLACE VIEW empvu10
(employee_number, employee_name, job_title)
AS SELECT employee_id, last_name, job_id
FROM employees
WHERE department_id = 10
WITH READ ONLY;
VIEW的删除
我们可以用DROP VIEW xxx;来删除VIEW
DROP VIEW empvu80;
SQL SEQUENCE(序列)
序列是SQL中的某一种数据类型,它符合以下的特征:
• Automatically generates unique numbers
• Is a sharable object
• Is typically used to create a primary key value
• Replaces application code
• Speeds up the efficiency of accessing sequence values when cached in memory
SEQUENCE的创建
我们可以用下列命令创建一个序列
CREATE SEQUENCE dept_deptid_seq
INCREMENT BY 10
START WITH 300
MAXVALUE 9999
NOCACHE
NOCYCLE;
上述命令的含义是:我们创建一个序列,这个序列的首项是300,最大的末项不能超过9999,公差是10;且这个序列无需缓存,且不是循环数列。
序列的使用
我们可以用以下的关键字去使用序列,假设序列的名字为seq
seq.CURRVAL 返回当前的项,然后当前项没有任何的变化。
seq.NEXTVAL 返回当前的项,然后当前的项+=公差。
假设首项为300,公差为10,访问了四次,则依次返回300,310,320,330。
我们可以通过不断地调用seq.NEXTVAL来实现主键的生成。
基于序列的元素插入
我们可以用INSERT和SEQUENCE进行数据的插入
其中department_id由SEQUENCE自动生成
INSERT INTO departments(department_id,
department_name, location_id)
VALUES (dept_deptid_seq.NEXTVAL,
'Support', 2500);
调用过一次后,我们可以用以下语句查看dept_deptid_seq.NEXTVAL的值
SELECT dept_deptid_seq.CURRVAL
FROM dual;
输出如下:
CURRVAL
----------
300
序列的修改
我们可以用ALTER SEQUENCE命令进行序列的修改
ALTER SEQUENCE dept_deptid_seq
INCREMENT BY 20
MAXVALUE 999999
NOCACHE
NOCYCLE;
这个命令,可以修改公差为20,但是不改变当前的值
序列的删除
我们可以用DROP SEQUENCE xxx 来删除掉某个序列
SQL> DROP SEQUENCE dept_deptid_seq;
序列已删除。
SQL INDEX(索引)
SQL 索引(Index)用于提高数据表的查询速度。一个表可以创建多个索引,一个索引可以包含一个或者多个字段。
不使用索引,数据库引擎将遍历整个表。
从表面上看,索引类似于书的目录,在没有目录的情况下,要从书中查找某项内容就必须阅读全文,而有了目录之后,通过页码就可以很快定位到相关内容。
从本质上看,索引是根据表的一个或者多个字段生成的子表,该子表中的数据已经进行了排序。子表除了包含指定字段中的数据,还包含一个 rowid 列,用于存储当前记录在原始表中的位置。用户无法看到索引,它只是用来加快查询速度。
为了提高查询效率,便于后期维护,索引都是基于某种数据结构而创建的,比如 B+ 树、B- 树、位图等。
INDEX的创建
我们可以用CREATE INDEX命令创建
CREATE INDEX upper_dept_name_idx
ON departments(UPPER(department_name));
注意:INDEX可以包含多行,比如下面的指令
CREATE INDEX employees ix
ON employees last_name, job_id, salary;
注意:我们需要将最常查询的内容,放在最前面(比如说last_name)
INDEX的查询
INDEX的使用,直接用SELECT进行即可
SELECT *
FROM departments
WHERE UPPER(department_name) = 'SALES';
输出如下:
DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID
------------- ------------------------------------------------------------ ---------- -----------
80 Sales 145 2500
INDEX的删除
一样可以用DROM INDEX命令删除
SQL Synonyms (别名)
Simplify access to objects by creating a synonym
(another name for an object). With synonyms, you can:
• Ease referring to a table owned by another user
• Shorten lengthy object names
懒得翻译了
Synonyms的创建
代码如下
CREATE SYNONYM d_sum
FOR dept_sum_vu;
创建以后,我们就可以用d_sum来表示dept_sum_vu,就不用输入过多的内容了。