`

数据库的复,view,index,sequence

阅读更多

 

ORACLE SQL DAY08

Top

  1. 创建一张表account_90,表结构与account一致,没有数据
  2. account_90表中包含所有的90后客户
  3. 通过演示理解什么是视图
  4. 每个客户选择了哪些资费标准
  5. 视图的维护
  6. 视图中的with check option约束
  7. 视图中的with read only约束
  8. 创建唯一性索引
  9. 创建联合索引
  10. 创建函数索引
  11. 序列号的应用场景和实现

1 创建一张表account_90,表结构与account一致,没有数据

1.1 问题

创建一张与account表结构一样的表account_90,表中不包含数据。

1.2 方案

在create table中可以嵌套SELECT语句,即子查询。若子查询的返回记录数为0,新建的表就只有结构。1 = 2是永假式,任何表都不会返回记录。

 
  1. where 1 = 2

1.3 实现

代码实现:

 
  1. create tableaccount_90
  2. as
  3. select * from account
  4. where 1 = 2 ;

2 account_90表中包含所有的90后客户

2.1 问题

account_90表中包含所有的90后客户。

2.2 方案

在insert中可以嵌套SELECT语句,即子查询。出生日期是90后的客户通过子查询实现。

 
  1. select * from account
  2. whereto_char(birthdate,'yyyy') between 1990 and 1999;

2.3 实现

代码实现:

 
  1. insert intoaccount_90
  2. select * from account
  3. whereto_char(birthdate,'yyyy') between 1990 and 1999;

2.4 扩展

3 通过演示理解什么是视图

3.1 问题

理解什么是视图,通过实验证明之。

3.2 方案

表是数据库对象,视图是另一种。它们既有相似之处,也有很大区别。通过演示,帮助同学们理解什么是视图?

3.3 实现

创建一张表,插入记录,提交。

 
  1. drop table testpurge;
  2. create tabletest(
  3. c1number,
  4. c2number);
  5. insert into testvalues (1,1);
  6. insert into testvalues (1,2);
  7. insert into testvalues (2,2);
  8. commit;

用DDL语句创建一张视图,我们可以像操作表那样操作视图。

 
  1. create or replace viewtest_v1
  2. as
  3. select * from test
  4. wherec1 = 1;
  5. desctest_v1
  6. NameNull? Type
  7. ----------------------------------------- -------- --------
  8. C1 NUMBER
  9. C2 NUMBER
  10. select * fromtest_v1;
  11. C1 C2
  12. ---------- ----------
  13. 1 1
  14. 1 2

向视图test_v1中插入一条记录(1,3),查看test_v1和test中的变化

 
  1. insert intotest_v1values (1,3);
  2. select * fromtest_v1;
  3. C1 C2
  4. ---------- ----------
  5. 1 1
  6. 1 2
  7. 1 3
  8. select * fromtest;
  9. SQL> select * fromtest;
  10. C1 C2
  11. ---------- ----------
  12. 1 1
  13. 1 2
  14. 2 2
  15. 1 3

向表test中插入一条记录(1,4),查看test_v1和test中的变化:

 
  1. insert into testvalues (1,4);
  2. select * fromtest_v1;
  3. C1 C2
  4. ---------- ----------
  5. 1 1
  6. 1 2
  7. 1 3
  8. 1 4
  9. select * fromtest;
  10. C1 C2
  11. ---------- ----------
  12. 1 1
  13. 1 2
  14. 2 2
  15. 1 3
  16. 1 4

向视图test_v1中插入一条记录(2,3),查看test_v1和test中的变化

 
  1. insert intotest_v1values (2,3);
  2. select * fromtest_v1;
  3. C1 C2
  4. ---------- ----------
  5. 1 1
  6. 1 2
  7. 1 3
  8. 1 4
  9. select * fromtest;
  10. C1 C2
  11. ---------- ----------
  12. 1 1
  13. 1 2
  14. 2 2
  15. 1 3
  16. 1 4
  17. 2 3

通过上述演示,我们发现视图类似于windows中的快捷方式。结论:视图就是一条SELECT语句,不占用单独的存储空间,从视图中查询实际是执行视图对应的SELECT语句。

 
  1. selectview_name,text fromuser_views
  2. whereview_name = 'TEST_V1';
  3. VIEW_NAME     TEXT
  4. ---------- ---------------------------
  5. TEST_V1     select "C1","C2" from test
  6.     wherec1 = 1

3.4 扩展

4 每个客户选择了哪些资费标准

4.1 问题

创建一张视图,包含客户名称account表的real_name,unix服务器ip地址service表的unix_host, 资费编号cost表的id,资费信息描述cost表的descr。结果集中值包含开通了远程登录业务的客户。

图 - 1

4.2 方案

写创建视图语句的核心是写SELECT语句,视图中包含的列来自account表、service表、cost表,即三张表的连接操作。

 
  1. from account a join service s
  2. ona.id = s.account_id
  3. join cost c
  4. ons.cost_id = c.id;

每多一张表会多一个join on操作。

4.3 实现

代码实现:

 
  1. create or replace viewaccount_cost_v
  2. as
  3. selecta.real_name,s.unix_host,c.id,c.descr
  4. from account a join service s
  5. ona.id = s.account_id
  6. join cost c
  7. ons.cost_id = c.id;

4.4 扩展

所有的客户都在结果集中

图 - 2

代码实现如下:

 
  1. create or replace viewaccount_cost_v
  2. as
  3. selecta.real_name,s.unix_host,c.id,c.descr
  4. from account a left join service s
  5. ona.id = s.account_id
  6. left join cost c
  7. ons.cost_id = c.id;
  8. create or replace viewaccount_cost_v
  9. selecta.real_name,t.unix_host,t.descr
  10. from account a left join
  11. (selects.account_id,s.unix_host,c.descr
  12. from service s join cost c
  13. ons.cost_id = c.id) t
  14. ona.id = t.account_id
  15. create or replace viewaccount_cost_v
  16. as
  17. selecta.real_name,s.unix_host,c.id,c.descr
  18. from account a left join service s
  19. ona.id = s.account_id
  20. left join cost c
  21. ons.cost_id = c.id;
  22. create or replace viewaccount_cost_v
  23. as
  24. selectreal_name,c.name
  25. from (select *
  26. from account a left join service s
  27. ona.id=s.account_id) aa left join cost c
  28. onaa.cost_id =c.id

5 视图的维护

5.1 问题

若将源表删除,基于源表的视图会发生怎样的变化?

5.2 方案

视图是一个依赖表的数据库对象,查询视图最终都要通过查询源表实现。如果源表的结构发生变化,对视图的操作就有可能出问题。查看视图的状态是帮助我们发现视图是否可用的方法。

5.3 实现

代码实现如下:

视图test_v1基于表test,此时它的状态为valid:

 
  1. selectview_name,text fromuser_views
  2. whereview_name = 'TEST_V1';
  3. VIEW_NAME     TEXT
  4. ---------- ---------------------------
  5. TEST_V1     select "C1","C2" from test
  6.     wherec1 = 1
  7. columnobject_name format a15
  8. columnobject_type format a10
  9. selectobject_name,object_type,status fromuser_objects
  10. whereobject_name = 'TEST_V1';
  11. OBJECT_NAMEOBJECT_TYP STATUS
  12. --------------- ---------- ------
  13. TEST_V1 VIEW VALID

将test表删除,检查视图test_v1的状态:

 
  1. drop table testpurge;
  2. desctest_v1
  3. ERROR:
  4. ORA-24372: invalid object for describe
  5. 提示:视图test_v1是无效的数据库对象
  6. select * fromtest_v1;
  7. ERROR at line 1:
  8. ORA-04063: view "JSD1302.TEST_V1" has errors
  9. 提示:视图test_v1有错误
  10. selectobject_name,object_type,status fromuser_objects
  11. whereobject_name = 'TEST_V1';
  12. OBJECT_NAMEOBJECT_TYP STATUS
  13. --------------- ---------- -------
  14. TEST_V1 VIEW INVALID
  15. 提示:test_v1的状态转变为无效INVALID。
  16. alter viewtest_v1compile;
  17. Warning: View altered with compilationerrors.
  18. 提示:在不做任何修改的情况下,重新编译视图仍旧出错。
  19. column text format a40
  20. column name format a10
  21. set linesize 200
  22. select * fromuser_errors;
  23. NAME TYPE SEQUENCE LINE POSITION TEXT ATTRIBUTEMESSAGE_NUMBER
  24. ------- ------ -- -- -- ------------------------------------- ----- -
  25. TEST_V1 VIEW 1 0 0 ORA-00942:table or view does not exist ERROR 0
  26. 提示:编译出错的原因是test表不存在。
  27. 创建test表以解决表不存在问题。
  28. create tabletest(c1number,c2number);
  29. selectobject_name,object_type,status fromuser_objects
  30. whereobject_name = 'TEST_V1';
  31. OBJECT_NAMEOBJECT_TYP STATUS
  32. --------------- ---------- -------
  33. TEST_V1 VIEW INVALID
  34. select * fromtest_v1;
  35. no rows selected
  36. OBJECT_NAMEOBJECT_TYP STATUS
  37. --------------- ---------- -------
  38. TEST_V1 VIEW VALID
  39. 原因:当drop源表,所有依赖源表的视图都将变为invalid。即视图本身存在,因为源表的丢失已经不能对视图正常操作了;当重新定义源表后,再次查询视图,系统先会对其编译:alterview_namecompile;若编译成功,可以正常操作视图。
  40. 结论:对源表进行DDL操作后,需要检查数据库对象的状态是否有invalid,若有,需要改正。

5.4 扩展

6 视图中的with check option约束

6.1 问题

通过视图test_v1可以插入(2,3),但从视图中不能查询到该记录,这样的情况不符合逻辑,怎样避免?

6.2 方案

可以对视图定义约束,with check option约束就是用来解决能对视图进行DML操作却不能SELECT的问题。

 
  1. whereos_usernamelike 'h%'

6.3 实现

在创建视图时增加with check option约束,该约束要求通过视图插入的记录必须符合where条件。

 
  1. create or replace viewtest_ck
  2. as
  3. select * from test
  4. wherec1 = 1 with checkoption;
  5. insert intotest_ckvalues (2,3);
  6. ERROR at line 1:
  7. ORA-01402: view WITH CHECK OPTIONwhere-clause violation

6.4 扩展

7 视图中的with read only约束

7.1 问题

对于简单视图来说,如何实现不允许DML操作?

7.2 方案

在创建视图时增加with read only约束,该约束能够实现只读。

7.3 实现

在创建视图时增加with read only约束,该约束要求对视图只能查询,不能做DML操作。

 
  1. create or replace viewtest_ro
  2. as
  3. select * from test
  4. wherec1 = 1 with readonly;
  5. insert intotest_rovalues (1,5);
  6. ERROR at line 1:
  7. ORA-01733: virtual column not allowed here

7.4 扩展

8 创建唯一性索引

8.1 问题

为表中的列创建唯一性索引。

8.2 方案

oracle提供了一种索引形式是唯一性索引,语法是:

 
  1. create unique index indname
  2. ontabname (colname);

要求该列的取值必须唯一。

8.3 实现

代码实现:

 
  1. create tabletest(
  2. c1 number constrainttest_c1_pk primarykey);
  3. insert into testvalues (1);
  4. insert into testvalues (1);
  5. ERROR at line 1:
  6. ORA-00001: uniqueconstraint (JSD1302.TEST_C1_PK) violated
  7. 第二条insert语句违反了唯一性约束
  8. alter table test drop primarykey;
  9. create unique indextest_c1_uniidx
  10. ontest(c1);
  11. insert into testvalues (1);
  12. insert into testvalues (1);
  13. ERROR at line 1:
  14. ORA-00001: uniqueconstraint (JSD1302.TEST_C1_UNIIDX) violated
  15. 注意:唯一性约束的名字是唯一性索引的名字
  16. 结论:唯一性约束是通过唯一性索引实现的,二者是等价的。

8.4 扩展

9 创建联合索引

9.1 问题

为表中的多列创建索引。

9.2 方案

oracle提供了一种索引形式是多列索引,在on关键字后的()里可以跟多列。如果有两列经常在一起查询,适合建多列索引。

9.3 实现

代码实现

 
  1. create tabletest(
  2. c1 number constrainttest_c1_pk primarykey,
  3. c2number,
  4. c3number);
  5. create indextest_c2_c3_idx
  6. ontest(c2,c3);

9.4 扩展

10 创建函数索引

10.1 问题

oracle为什么提供函数索引?怎样创建函数索引?

10.2 方案

若在c2列上创建普通索引,where round(c2) = 10是用不了该索引的,oracle仍然会用全表扫描的方式查询数据,要想提高查询效率,必须使用函数索引。

 
  1. ontabname (funame(colname,..))

10.3 实现

代码实现

 
  1. create tabletest(
  2. c1 number constrainttest_c1_pk primarykey,
  3. c2number,
  4. c3number);
  5. create indextest_c2_funidx
  6. ontest(round(c2));

10.4 扩展

11 序列号的应用场景和实现

11.1 问题

oracle为什么提供sequence?怎样创建sequence?

11.2 方案

表中的PK/UK列要求取值一定要唯一,在程序执行尤其是并发执行时,怎样保证每次插入的值是唯一的。oracle提供了自己的解决方案:使用sequence。

 
  1. create sequenceseq_name
  2. [increment by 1|integer]
  3. [start withinteger]
  4. [maxvalueinteger|nomaxvalue]
  5. [minvalueinteger|nominvalue]
  6. [cycle|nocycle]
  7. [cache 20|integer|nocache]

11.3 实现

代码实现

 
  1. drop table testpurge;
  2. create tabletest(
  3. c1 number constrainttest_c1_pk primarykey);
  4. drop sequences_test_c1;
  5. create sequences_test_c1
  6. start with 1302001;
  7. insert into testvalues (s_test_c1.nextval);
  8. insert into testvalues (s_test_c1.nextval);
  9. commit;
  10. insert into testvalues (s_test_c1.nextval);
  11. rollback;
  12. insert into testvalues (s_test_c1.nextval);
  13. select * fromtest;
  14. C1
  15. ----------
  16. 1302001
  17. 1302002
  18. 1302004
  19. selects_test_c1.currval fromdual;
  20. CURRVAL
  21. ----------
  22. 1302004
  23. selectsequence_name,cache_size,last_number
  24. fromuser_sequences;
  25. SEQUENCE_NAMECACHE_SIZELAST_NUMBER
  26. ------------------------------ ---------- -----------
  27. S_TEST_C1 20 1302021

11.4 扩展

分享到:
评论

相关推荐

    Oracle数据库、SQL

    二十、 数据库对象:序列号sequence 44 20.1什么是sequence 44 20.2创建sequence 44 20.3缺省是nocycle(不循环) 44 20.4缺省cache 20 44 二十一、 其他注意事项 46 21.1删除表,删除列,删除列中的值 46 21.2多对...

    Oracle_review

    二、SQL 结构化查询语言 程序员、DBA和数据库管理系统DBMS交互的语言,... create 创建 database table view index sequence drop 删除 database table view index sequence alter 改变 table view 会自动提交事物

    jfsky.com-Oracle数据库基础知识

    1.3.4 视图(View) 18 1.3.5 索引(Index) 18 1.3.6 同义词(Synonym) 19 1.3.7 序列(Sequence) 19 1.3.8 数据库链(Database Link) 20 第2章 管理ORACLE数据库 21 2.1 基本概念 21 2.1.1 数据字典 21 2.1.2 ...

    oracle基础教程

    1.3.4 视图(View) 18 1.3.5 索引(Index) 18 1.3.6 同义词(Synonym) 19 1.3.7 序列(Sequence) 19 1.3.8 数据库链(Database Link) 20 第2章 管理ORACLE数据库 21 2.1 基本概念 21 2.1.1 数据字典 21 2.1.2 ...

    ORACLE数据库基础知识-华为维护资料

    1.3.3 视图(View) 15 1.3.4 索引(Index) 16 1.3.5 同义词(Synonym) 16 1.3.6 序列(Sequence) 17 1.3.7 数据库链(Database Link) 17 第2章 管理ORACLE数据库 19 2.1 启动与关闭 19 2.1.1 权限 19 2.1.2 ...

    数据库设计规范(3).doc

    3 3.1 数据库命名规则 3 3.2 数据库对象命名的一般原则 3 3.3 表空间(Tablespace)命名规则 4 3.4 表(Table)命名规则 4 3.5 字段命名规则 4 3.6 视图(View)命名规则 4 3.7 序列(Sequence)命名规则 5 3.8 存储过程...

    aix常用命令

    18 1.3.5 索引(Index) 18 1.3.6 同义词(Synonym) 19 1.3.7 序列(Sequence) 19 1.3.8 数据库链(Database Link) 20 第2章 管理ORACLE数据库 21 2.1 基本概念 21 2.1.1 数据字典 21 2.1.2 事务管理 23 2.1.3 ...

    Oracle & SQL 入门精简介绍

    Oracle & SQL 入门精简介绍 ------------------------------ 一、Oracle数据库中常用的数据类型 二、数据库查询 三、SQL常用的命令分类及例子 四、Oracle数据库函数 五、表连接(关联查询) ...十四、索引(index)

    Oracle8i_9i数据库基础

    §4.2 实体视图(MATERIALIZED VIEW) 131 §4.2.1 创建实体视图 131 §4.2.2 创建实体视图日志 137 §4.2.3 修改实体视图 139 §4.2.4 修改实体视图日志 141 §4.2.45 实体视图完整例子 142 §4.3 序号(sequence) 146...

    非常详细的sql大全

    CREATE SEQUENCE -- 创建一个新的序列发生器 CREATE TABLE -- 定义一个新表 CREATE TABLE AS -- 从一条查询的结果中创建一个新表 CREATE TRIGGER -- 定义一个新的触发器 CREATE TYPE -- 定义一个新的数据类型 CREATE...

    orcale常用命令

    ORACLE的数据字典是数据库的重要组成部分之一,它随着数据库的产生而产生, 随着数据库的变化而变化, 体现为sys用户下的一些表和视图。数据字典名称是大写的英文字符。 数据字典里存有用户信息、用户的权限信息、...

    Oracle帮助文档

    序列(sequence) 7.约束(constraint) 8.视图(view) 9.索引(index) 10.数据类型 11.基本查询 12.查寻常用操作 13.语言四大类 14.聚合函数 15.函数 16.操作符 17.多表查询 18.子查询 19.伪列 数据库组件...

    db2-技术经验总结

    1.41. view application 79 1.42. kill application 79 1.43. lock table(x) 79 1.44. lock table(s) 80 1.45. 列出所有的系统表 80 1.46. 列出系统数据库目录 80 1.47. 显示当前活动数据库 80 1.48. 查看命令选项 ...

    尚硅谷——企业SQL面试复习与测试

    题目:企业SQL面试复习与测试 1.常见的数据库对象有哪些? 表(table) 视图(view) 序列(sequence) 索引(index) 同义词(synonym) 存储过程(procedure) 存储函数(function) 触发器(trigger)

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    主要包括select, update, insert, alter, index, delete, all其中all包括所有权限。  授予实体权限 用法:grant 实体权限1[,实体权限2]… on 表名 to用户名1[,用户名2]…. 例子:  实体权限回收 用法:revoke ...

    Oracle事例

    sql> create [unique] index index_name on table_name(column,.. asc/desc) tablespace sql> tablespace_name [pctfree integer] [initrans integer] [maxtrans integer] sql> [logging | nologging] [nosort] ...

    Oracle 10g 学习笔记

    │ view.sql │ ├─08 序列同义词 │ sequence.sql │ ├─09 用户管理 │ user.jpg │ user.sql │ ├─10 嵌套表 可变数组 │ createType.sql │ ├─11 PLSQLl语法 │ plsql.sql │ ├─12 索引 │ index....

    最全的oracle常用命令大全.txt

    ORACLE的数据字典是数据库的重要组成部分之一,它随着数据库的产生而产生, 随着数据库的变化而变化, 体现为sys用户下的一些表和视图。数据字典名称是大写的英文字符。 数据字典里存有用户信息、用户的权限信息、...

    sql总结.doc

    (3)Create index 索引名 on 表名(字段名) (4)索引分为聚簇索引和非聚簇索引 (5)索引的作用 1.创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 2.可以加大数据的检索速度,这也是创建索引的主要原因。...

    RMAN测试演练即讲解

    5、 其他如table、index、function、procedure、view、sequence等。 六、 Rman备份的对象(主要包括Database、Tablespace、Datafile、Controlfile和Archivelog) Rman不能备份口令文件和初始化参数文件(也就是...

Global site tag (gtag.js) - Google Analytics