1 数据库对象(视图、序列、同义词、索引  都是DDL语句)
  2 
  3 1 视图
  4     视图是从一个或几个实体表(或视图)导出的表。它与实体表不同,视图本身是一个不包含任何真是数据的虚拟表。视图最终是定义在实体表之上的,对视图的一切操作最终也要转换为对实体表的操作。
  5     有经验的数据库设计人员往往会为开发者将各个复杂的SQL语句封装成一个个独立的视图。
  6 --创建视图
  7     CREATE [FORCE|NOFORCE] [OR REPLACE] VIEW 视图名称 [(别名1,别名2,...)]
  8         AS
  9     子查询 ;
 10     
 11     FORCE: 表示要创建视图的表不存在也可以创建视图。
 12     NOFORCE:(默认)表示要创建视图的表必须存在,否则无法创建视图。
 13     OR REPLACE : 表示视图的替换。如果创建的视图不存在,则创建新的视图;如果视图已经存在,则将其替换。
 14     
 15 --用例1:创建一张基本工资大于2000的雇员信息的视图
 16 CREATE VIEW v_myview
 17     AS
 18 SELECT * FROM emp WHERE sal>2000;
 19 
 20 --用例2: 查看视图是否已经创建
 21 SELECT * FROM tab WHERE tabtype='VIEW'    and lower(TNAME)='v_myview';
 22 SELECT view_name,text_length,text FROM user_views WHERE  lower(view_name)='v_myview';
 23 
 24 --用例3:替换 v_myview ,创建一张基本工资大于2000的雇员信息的视图,
 25 CREATE OR REPLACE VIEW v_myview
 26     AS
 27 SELECT * FROM emp WHERE sal>2000;
 28 
 29 --用例3:替换 v_myview ,为视图中查询的列起别名
 30 CREATE OR REPLACE VIEW v_myview
 31     (部门编号,部门名称,位置,人数,平均工资,总工资,最高工资,最低工资)
 32     AS
 33 SELECT d.deptno,d.dname,d.loc,
 34     COUNT(e.empno) count,
 35     NVL(ROUND(AVG(sal),2),0) avg,
 36     NVL(SUM(sal),0) sum,
 37     NVL(MAX(sal),0) max,
 38     NVL(min(sal),0) min
 39 FROM emp e,dept d
 40 WHERE e.deptno(+)=d.deptno
 41 GROUP BY d.deptno,d.dname,d.loc;
 42 
 43 --用例4:在视图上执行DML操作
 44     UPDATE 视图后,原表会同步更新,缺失字段默认为空。当用户对视图执行删除操作之后,会影响原始数据表中的数据。 但是无法通过多表映射的视图修改多个表。
 45 重点: 能否有其他方式可以通过视图同步更新多张数据表?
 46     视图如果由多张数据表组成,将无法进行增加及更新的操作。
 47     答: 利用触发器完成多表同时更新。
 48 
 49 1.1 WITH CHECK OPTION 子句: 保证视图的创建条件不被修改。
 50      在创建视图的时候需要使用WHERE 子句做一些条件限制,但是默认情况下视图创建完成之后,是可以通过视图修改在WHERE子句中所使用的字段内容,此时就需要通过 WITH CHECK OPTION 子句来保证视图的创建条件不被更新。
 51    语法:WITH CHECK OPTION 子句
 52    CREATE [FORCE|NOFORCE] [OR REPLACE] VIEW 视图名称 [(别名1,别名2,...)]
 53        AS
 54    子查询 [WITH CHECH OPTION [CONSTRAINT 约束名称]];
 55    
 56 --用例1:
 57    CREATE OR REPLACE VIEW v_emp20
 58        AS
 59    SELECT * FROM emp WHERE deptno=20
 60    WITH CHECK OPTION CONSTRAINT v_emp20_ck;
 61 
 62 1.2 WITH READ ONLY 子句: 创建只读视图,让视图的其他字段无法更新。
 63     语法:WITH READ ONLY 子句
 64     CREATE [FORCE|NOFORCE] [OR REPLACE] VIEW 视图名称 [(别名1,别名2,...)]
 65         AS
 66     子查询 [WITH CHECH OPTION [CONSTRAINT 约束名称]]
 67     [WITH READ ONLY]
 68     ;
 69     
 70 --用例1
 71     CREATE OR REPLACE VIEW v_emp20
 72         AS
 73     SELECT * FROM emp WHERE deptno=20
 74     WITH READ ONLY;
 75 --READ_ONLY 字段    
 76 SELECT view_name,text_length,text,READ_ONLY FROM user_views WHERE  lower(view_name)='v_myview';
 77 
 78 1.3 删除视图
 79     语法:DROP VIEW 视图名称;
 80 
 81 --用例1:
 82 DROP VIEW v_emp20;
 83 SELECT view_name,text_length,text,READ_ONLY FROM user_views WHERE  lower(view_name)='v_emp20';
 84 
 85 
 86 2 序列
 87     序列是Oracle 中最为重要的对象,利用序列可以实现数据表流水号(自动增长列)的操作。
 88 2.1 序列的作用及创建
 89     语法:序列的完整创建语法
 90     CREATE SEQUENCE 序列名称
 91     [INCREMENT BY 步长]
 92     [START WITH 开始值]
 93     [MAXVALUE 最大值|NOMAXVALUE]
 94     [MINVALUE 最小值|NOMINVALUE]
 95     [CYCLE|NOCYCLE]
 96     [CACHE 缓存大小|NOCACHE];
 97 
 98     SEQUENCE
 99 
100 --用例1:创建默认序列
101 CREATE SEQUENCE myseq;
102 --用例2:查看序列数据字典
103 SELECT * FROM user_sequences;
104     
105     字段说明:
106     SEQUENCE_NAME:表示序列的名称,此处的名称为之前创建的MYSEQ。
107     MIN_VALUE:此序列开始的默认最小值(默认是0)。
108     MAX_VALUE:此序列开始的默认最大值(默认是27个9 ,即 999999999999999999999999999)。
109     INCREMENT_BY:序列每次增长的步长,默认是1。
110     CYCLE_FLAG: 循环标记,如果是循环序列则显示Y,非循环序列则显示为N(默认为N)。
111     CACAHE_SIZE:序列操作的缓存量,默认是20 。
112     LAST_NUMBER:最后一次操作的值。
113     序列名称.currval: 表示取得当前序列已经增长的结果,重复调用多次后序列内容不会有任何变化,同时当前序列的大小(LAST_NUMBER)不会改变。
114     序列名称.nextval: 表示取得一个序列的下一次增长值,每调用一次,序列都会增长。
115     
116     
117 --用例3:通过 nextval 属性操作序列。
118 SELECT myseq.nextval FROM dual;
119 
120 --用例4:通过 currval 属性操作序列。
121 SELECT myseq.currval FROM dual;
122 
123 --用例5:创建一张 member 表,并使用序列进行ID列的自动增长操作。
124     DROP TABLE member PURGE;
125     DROP TABLE advice PURGE;
126     CREATE TABLE member(
127         mid NUMBER PRIMARY KEY,
128         name VARCHAR2(200) NOT NULL,
129         email VARCHAR2(50),
130         CONSTRAINT uk_email UNIQUE(email),
131         CONSTRAINT pk_mid PRIMARY KEY(mid)
132     ); 
133     INSERT INTO member(mid,name) VALUES(myseq.nextval,'XXXX学院');
134 
135 2.2 序列的删除
136     语法:
137     DROP SEQUENCE 序列名称;
138 
139 --用例1:删除 myseq 序列
140 DROP SEQUENCE myseq;
141 SELECT * FROM user_sequences;
142 
143 2.3 创建特殊功能的序列
144 --用例1:设置序列的增长步长 INCREMENT BY
145 CREATE SEQUENCE myseq INCREMENT BY 3;
146 SELECT * FROM user_sequences WHERE SEQUENCE_NAME='myseq';
147 
148 --用例2:设置序列的初始值 START WITH,创建序列,让其初始值设置为30,每次增长步长为2.
149     一个序列的默认初始值是1,用户在创建序列的时候可以直接通过 START WITH 属性设置。
150     CREATE SEQUENCE 序列名称 START WITH 开始值;
151 
152     DROP SEQUENCE myseq;
153     CREATE SEQUENCE myseq 
154         INCREMENT BY 3
155         START WITH 30;
156     
157     SELECT myseq.nextval FROM dual;
158 
159 --用例3:设置序列的缓存 CACHE 缓存大小|NOCACHE, 可能引起跳号的问题。
160     创建序列并由用户设置缓存操作。
161     CREATE SEQUENCE 序列名称 CACHE 缓存大小|NOCACHE。
162     
163     --创建序列,缓存设置为100 。
164     CREATE SEQUENCE myseq CACHE 100;
165 
166     --创建序列,不设置缓存 。
167     CREATE SEQUENCE myseq NOCACHE;
168 
169     SELECT cache_size,last_number FROM user_sequences;
170 
171 --用例4:设置循环序列。循环序列指的是一个序列在每次调用 nextval 属性后可以产生指定范围的数据。例如,现在希望一个序列的内容是在1/3/5/7/9 这5个数字之间循环,这就属于循环序列。
172     CREATE SEQUENCE 序列名称
173         [MAXVALUE 最大值|NOMAXVALUE]
174         [MINVALUE 最小值|NOMINVALUE]
175         [CYCLE|NOCYCLE];
176 
177     DROP SEQUENCE myseq;
178     CREATE SEQUENCE myseq 
179         START WITH 1
180         INCREMENT BY 2
181         MAXVALUE 10
182         MINVALUE 1
183         CYCLE 
184         CACHE 3;
185 
186 2.4 修改序列  (不建议修改数据库对象 )
187     语法:
188     ALTER SEQUENCE 序列名称
189         [INCREMENT BY 步长]
190         [START WITH 开始值]
191         [MAXVALUE 最大值|NOMAXVALUE]
192         [MINVALUE 最小值|NOMINVALUE]
193         [CYCLE|NOCYCLE]
194         [CACHE 缓存大小|NOCACHE];
195 
196 --用例1:修改 myseq 序列
197 ALTER SEQUENCE myseq
198     INCREMENT BY 10
199     MAXVALUE 98765
200     MINVALUE 1
201     CACHE 100;
202 
203 SELECT cache_size,last_number FROM user_sequences;
204     
205 2.5 自动序列,自动增长序列。
206 语法:
207 CREATE SEQUENCE 表名称(
208     列名称 类型 GENERATED BY DEFAULT AS IDENTITY(
209                                   [INCREMENT BY 步长]
210                                   [START WITH 开始值]  
211                                   [MAXVALUE 最大值|NOMAXVALUE] 
212                                   [MINVALUE 最小值|NOMINVALUE]
213                                   [CYCLE|NOCYCLE]
214                                   [CACHE 缓存大小|NOCACHE]),
215     列名称 类型 ,...                                  
216 );
217     
218 --用例1:创建带有自动增长列的数据表。
219 DROP SEQUENCE myseq PURGE;    
220 CREATE TABLE mytab(
221     mid NUMBER GENERATED BY DEFAULT AS IDENTITY(START WITH 1 INCREMENT BY 1),
222     name VARCHAR2(20) NOT NULL,
223     CONSTRAINT pk_mid PRIMARY KEY(mid)
224 );    
225 
226     
227 SELECT sequence_name,min_value,max_value,increment_by FROM user_sequences;    
228     
229 --用例2: 自动序列的删除
230     自动序列依附于数据表而存在,如果在执行数据表的删除操作时没有设置 PURGE 参数,那么表删除后序列依然会被保留,这时候不能利用 DROP SEQUENCE 命令删除序列,必须使用清空回收站的方式才可以删除。
231     PURGE recyclebin;    
232     
233     
234 3 同义词
235     数据库中所谓的同义词实际上就是指为一个数据库对象其一个其他名字。     
236 创建同义词语法:
237 CREATE [PUBLIC] SYNONYM 同义词名称 FOR 数据库对象;
238 
239 删除同义词语法:
240 DROP SYNONYM 同义词名称;
241 
242 --用例1:创建同义词    
243 CREATE  SYNONYM myemp FOR emp;
244 SELECT * FROM user_synonyms WHERE synonym_name='MYEMP';    
245 
246 --用例2:删除同义词
247 DROP SYNONYM myemp ;    
248 
249 --用例3:创建公共同义词 myemp
250 CREATE PUBLIC SYNONYM myemp FOR emp;    
251     
252     
253 4 Oracle 伪列    
254     在 Oracle 数据库中为了实现完整的关系数据库的功能,专门为用户提供了许多的伪列,像之前在讲解序列时所使用的 NEXTVAL 和 CURRVAL 就是两个默认提供的操作伪列。同时在前面使用的 SYSDATE 与 SYSTIMESTAMP 也属于伪列(而想查询使用 DUAL 称为伪表)。这些数据伪列并不是用户在建立数据库对象时有用户完成的,而是 Oracle 自动帮助用户建立的,用户只需要按照要求使用即可。另外两个重要的伪列,分别是 ROWNUM 和 ROWID 。
255        1. ROWID 伪列
256        2. ROWNUM 伪列
257        3. NEXTVAL、CURRVAL 
258        4. SYSDATE、SYSTIMESTAMP 
259        5. DUAL 伪表
260 
261 4.1 ROWID 伪列
262    在数据表中每一行所保存的记录,实际上 Oracle 都会默认为每条记录分配一个唯一的地址编号,而这个地址编号就是通过 ROWID 进行表示的,ROWID 本身是一个数据的伪列,所有的数据都利用 ROWID 进行数据定位。
263 
264 --用例1:   
265 SELECT ROWID,deptno,dname,loc FROM dept;
266 
267 读讲解ROWID 的组成:AAAWecAAGAAAAC2AAA:
268     1.数据对象号(data object number):AAAWec
269     2.相对文件号(relative file number):AAG
270     3.数据块号(block number):AAAAC2
271     4.数据行号(row number):AAA
272 
273 --ROWID 的操作函数:
274     1. DBMS_ROWID.rowid_object(ROWID) : 从一个 ROWID 中,取得数据对象号。
275     2. DBMS_ROWID.rowid_relative_fno(ROWID) : 从一个 ROWID 中,取得相对文件号。
276     3. DBMS_ROWID.rowid_block_number(ROWID) : 从一个 ROWID 中,取得数据块号。
277     4. DBMS_ROWID.rowid_row_number(ROWID) : 从一个 ROWID 中,取得数据行号。
278 
279 --拆分 ROWID,取数据。
280     SELECT ROWID,
281            DBMS_ROWID.rowid_object(ROWID),
282            DBMS_ROWID.rowid_relative_fno(ROWID),
283            DBMS_ROWID.rowid_block_number(ROWID),
284            DBMS_ROWID.rowid_row_number(ROWID),
285            deptno,dname,loc
286      FROM dept;
287 
288 -- 使用 ROWID 可以定位一个数据库中的任何数据行。因为一个段只能存在一个表空间内,所以通过使用数据对象号,Oracle 服务器就可以找到包含数据行的表空间。之后使用表空间中的相对文件号就可以确定文件,在利用数据块号就可以确定包含所需数据行的数据块,最后使用行号就可以定位数据行的行目录项。       
289 
290 --用例2 :经典题目
291    向 mydept 表中增加一些数据
292    INSERT INTO mydept(deptno,dname,loc) VALUES(10,'ACCOUNTING','NEW YORK');
293    INSERT INTO mydept(deptno,dname,loc) VALUES(10,'ACCOUNTING','NEW YORK');
294    INSERT INTO mydept(deptno,dname,loc) VALUES(20,'RESEARCH','DALLAS');
295    INSERT INTO mydept(deptno,dname,loc) VALUES(20,'RESEARCH','DALLAS');
296    INSERT INTO mydept(deptno,dname,loc) VALUES(20,'RESEARCH','DALLAS');
297 
298 现在要求用户将所有重复的数据删除到只剩1条,即:现在表中有3个10部门的信息,要求值保留1个10部门的信息,删除重复数据后,mydept表应只剩下4行单独的数据。
299 答案:
300    --1 对mydept 表分组,统计出唯一的ROWID数据。
301    SELECT deptno,dname,loc,MIN(ROWID)
302    FROM mydept
303    GROUP BY deptno,dname,loc;
304    
305    --2 编写删除语句删除重复数据(必须要按照deptno 部门分组,否则会只保留一个值。)
306    DELETE FROM mydept
307    WHERE ROWID NOT IN (
308        SELECT MIN(ROWID) 
309        FROM mydept 
310        GROUP BY deptno);
311 
312 4.2 ROWNUM 伪列
313     ROWNUM 表示的是一个数据行编号的伪列,它的内容是在用户查询数据的时候,为用户动态分配的一个数字(行号)。
314     ROWNUM作用:
315         1.取出一个查询的第一行记录。
316         2.取出一个查询的前N行记录。
317 --用例1:   
318 SELECT ROWNUM,deptno,dname,loc FROM dept;
319 
320 --用例2:取出一个查询的第一行记录。
321 SELECT * FROM emp WHERE ROWNUM=1;
322 
323 --用例3:取出一个查询的前N行记录。
324 SELECT * FROM emp WHERE ROWNUM>5;
325 
326 --用例4:经典应用,分页显示。ROWNUM 数据伪列前N 行查询的语法
327 SELECT * FROM(
328     SELECT 列1[,列2,...],ROWNUM rownum 别名
329     FROM 表名称 [别名]
330     WHERE ROWNUM <= (currentPage(当前所在页) * lineSize(每页显示记录行数)) temp
331 WHERE temp.rownum 别名 >(currentPage(当前所在页)-1)*lineSize(每页显示记录行数);
332 
333 
334 --显示雇员表中前5条记录。
335 SELECT * FROM(
336     SELECT empno,ename,job,hiredate,sal,mgr,deptno,ROWNUM rn
337     FROM emp WHERE ROWNUM<=5) temp
338 ) temp.rn>0;
339 
340 
341 
342 4.3 ORACLE 12C 新特性,(方便数据分页显示操作,指定范围内的操作数据)
343 FETCH语法:
344     SELECT [DISTIINCT] [][] 
345     FROM 表名称1 [表别名1],表名称2 [表别名2],...
346     [WHERE 条件(s)]
347     [GROUP BY 分组字段1,分组字段2]
348     [HAVING 过滤条件(s)]
349     [ORDER BY 排序字段 ASC|DESC]
350     [FETCH FIRST 行数]|[OFFSET 开始位置 ROWS FETCH NEXT 个数]|[FETCH NEXT 百分比 PERCENT] ROW ONLY 
351     
352     1.获取前N行记录:FETCH FIRST 行数  ROW ONLY ;
353     2.取得指定范围的记录: OFFSET 开始位置 ROWS FETCH NEXT 个数 ROW ONLY ;
354     3.按照百分比取得记录:FETCH NEXT 百分比 PERCENT ROW ONLY 
355 
356 --用例1:取得emp表中的前5行记录。
357 SELECT * FROM emp FETCH FIRST 5 ROW ONLY;
358 
359 --用例2:为数据排序,取得前5行记录。
360 SELECT * FROM emp 
361 ORDER BY sal DESC 
362 FETCH FIRST 5 ROW ONLY;
363 
364 --用例3:取得指定范围的记录,取得4~5条记录。(下标为0,所有行从0行开始)
365 SELECT * FROM emp 
366 ORDER BY sal DESC 
367 OFFSET 3 ROWS FETCH NEXT 2 ROW ONLY; /*下标为0,所有行从0行开始*/
368 
369 --用例4:按百分比取部分数据。
370 SELECT * FROM emp 
371 ORDER BY sal DESC 
372 FETCH NEXT 10 PERCENT ROW ONLY ;
373 
374 
375 5 索引 (利用ROWID查找是最高效的做法)
376     在数据库中,索引是一种专门用于数据库查询操作性能的一种手段。在 Oracle中,为了维护这种查询性能,需要对某一类数据进行指定结构的排列。但是针对 Oracle 中,针对不同的情况会有不同的索引使用。
377     索引有:
378       1. B树索引
379       2. 降序索引
380       3. 位图索引
381       4. 函数索引
382 
383 5.1 B*Tree 索引 (二叉树索引)
384    B树索引是最基本的索引结构,在 Oracle 中默认建立的索引就是此类型索引。一般B树索引在检索高基数数列(该列上的重复内容较少或没有)的时候可以提高性能的检索操作。
385    原理:
386       1. 取得第一个数据作为根节点。
387       2. 比根节点小的数据放在左子树,比根节点大的数据放在右子树。      
388 
389 --在Oracle 中想要创建 B*Tree 索引,有以下两种方式:
390     1. 当某一列上设置了主键约束或唯一约束,则会自动创建索引。(PK、UK)
391     2. 利用命令直接创建索引: CREATE INDEX [用户名.]索引名称 ON [用户名.]表名称 (列名称 [ASC|DESC],...);
392 
393 --用例1:
394 CREATE INDEX emp_sal_ind ON emp(sal);
395 --查看哪张表上存在索引。
396 SELECT index_name,index_type,table_owner,table_name,uniqueness,status FROM user_indexes;
397 --查看索引所在列。
398 SELECT * FROM user_ind_columns WHERE lower(index_name)='emp_sal_ind';
399 
400 --用例2:在 hiredate 字段上设置降序索引
401 CREATE INDEX emp_hiredate_ind_desc ON emp(hiredate);
402 
403 --用例3:创建函数索引
404 CREATE INDEX emp_ename_ind ON emp(LOWER(sal));
405 
406 
407 5.2 位图索引
408     如果现在某一列上的数据都数据低基数(Low - Cardinality)列的时候,就可以利用位图索引来提升查询性能。例如deptno,春夏秋冬。
409     位图索引以一种压缩数据的格式存放,因此所占用的磁盘空间要比 B*Tree 索引小很多。
410 
411 语法:
412 创建位图索引:
413     CREATE BITMAP INDEX [用户名.]索引名称 ON [用户名.]表名称 (列名称 [ASC|DESC],...);
414 --用例1:
415 CREATE BITMAP INDEX emp_deptno_ind ON emp(deptno);
416 SELECT index_name,index_type,table_owner,table_name,uniqueness,status FROM user_indexes;
417 
418 5.3 删除索引
419 语法:
420 DROP INDEX 索引名称;
421 --用例1:
422 DROP INDEX emp_deptno_ind;

 

posted on 2023-04-03 20:37  言溪清流  阅读(90)  评论(0)    收藏  举报