Oracle學習筆記摘錄5-----表 / 序列 /視圖 / 索引 / 同義詞

 數據庫對象
<1>表(約束)
<2>如何自動編號
SQLserver
  --IDENTITY屬性
  create table test(
    xh int identity(1,2) primary key,
    name varchar(20)
);
  insert into test(name) values ('mike');

ORACLE
  一個對象(序列sequence)
  --最簡單的一個序列,從1開始每次增加1,最大值38位精度10的38次方
和SQLSERVEr中的IDENTITY(1,1)類似
   create sequence seq1;

訪問其中的值
  使用2個僞列 nextval,currval
    select seq1.nextval from dual;--新值
    
    select seq1.currval from dual; --當前值
 
從3開始每次增加2
  3,5,7,9
  create sequence seq2
        start with 3
        increment by 2;

從5開始每次增加5,最大值30,最小值是1
 循環序列(到最大值後回到最小值)

    5,10,15,20,25,30,1,6,11,......
  create sequence seq3
     start with 5      --起始值
     increment by 5    --步長
     maxvalue 30       --最大值
     minvalue 1        --最小值
     cycle             --循環
     cache 4           --緩存4個數
  默認值cache是20個

 取5的時候,內存中已經算出了10,15,20,25
  取10的時候,直接取內存中的數

如何用到表中
   create table testa(
     xh number(4) primary key,
     nm varchar2(20));
   
 xh字段要實現自動編號
   insert into testa values (seq3.nextval,'MIKE');
   insert into testa values (seq3.nextval,'JOHN');

自動編號 保證唯一性 實際中一般用它做主鍵
a) 對emp新加入的員工的編號是7944,7954,7964,....
--建立sequence
  create sequence s_emp
    start with 7935;
--使用  nextval
  insert into emp(empno,ename) values (s_emp.nextval,'張三');
     insert into emp(empno,ename) values (s_emp.nextval,'李四');

b) 排名次
  把員工按工資高低按名次排列
--加一個名次字段ord
 alter table emp add (ord number(3));
--更新ord(名次=工資比我高的人數+1)
 update emp a set ord = (select count(*)+1
from emp where sal > a.sal);

--刪除序列seq1
  drop sequence seq1;

<3> 視圖(VIEW)
  create or replace view <名字> as
   <select 語句>
例子
  create or replace view emp_view as
    select ename,empno,sal from emp;

  select * from emp_view;
轉化爲一個子查詢來執行
  select * from (select ename,empno,sal from emp);

視圖中是否存放數據???
  不存放數據,存放的是查詢語句
  隱藏數據

通過視圖能改表中的數據嗎??
  是可以的,但是有條件限制的
   限制條件是:建立視圖的查詢語句必須是一個簡單的select(只查詢一個表,並且不含有分組函數),就可以改表中的數據了
   select * from emp_view;

   update emp_view set sal = 3000;

 select a.*,(select count(*) from
emp where deptno = a.deptno) as rs
from dept a;

create or replace view deptrs
as  select a.*,(select count(*) from
emp where deptno = a.deptno) as rs
from dept a;

select * from deptrs;

能否通過視圖去改表中的數據呢???
         有條件的可以:
           <1>建立視圖的select語句必須是簡單的select語句
               簡單:不能是多表的查詢
                    不能有分組函數
           <2>建立視圖的時候不能帶with readonly關鍵字
     create or replace view emp_v2 as --select語句
         select empno,ename,sal from emp
         with read only;
                   
  可以改的情況:
     1)create or replace view emp_v1 as --select語句
         select empno,ename,sal,comm from emp;
         
     update emp_v1 set comm = 1000
         where empno=7934;
 
     select * from emp;   --發現數據修改了

     2)create or replace view emp_v3
        as
          select empno,ename,hiredate,sal,deptno
          from emp
          where deptno = 10;

       update emp_v3 set deptno=20 where empno=7782;
 
       select * from emp_V3; --7782的數據沒有了

    3)create or replace view emp_v4
      as select empno,ename,sal,comm from emp
      where sal > 3000
      with check option;
       with check option保證where總是成立
        修改:如果你要把數據從>3000 改成 < 3000 那麼就不行
        插入:如果數據不滿足sal>3000,那麼也不讓通過視圖插入
        刪除:不受條件的限制

 用視圖的時候 不要去通過視圖來修改基表
  視圖只用於 數據的查詢就夠了
 



<4>數據字典
 一套視圖(系統定義的)來管理所建立的對象
 select * from dict; --查詢到所有的數據字典表
 a) 查看用戶下的表
   connect scott/tiger
   select table_name from user_tables;
 b) 查看用戶下的對象
    connect scott/tiger
    column object_name format a20 --字段格式是字符的20位長度
    select object_name,object_type
    from user_objects
    order by object_type;  --用戶所擁有的對象

    select object_name,object_type
    from user_objects
    WHERE object_type='TABLE'; --用戶所擁有的表
 
    select object_name,object_type
    from user_objects
    WHERE object_type='INDEX'; --用戶所擁有的索引
 c) emp和dept的關係
     emp(deptno reference dept(deptno))

   select a.table_name,a.column_name,
       c.table_name as "引用它的表",c.column_name "引用它的列"
from user_cons_columns a,
     user_constraints b,
     user_constraints d,
     user_cons_columns c
where a.constraint_name = b.constraint_name
and d.constraint_name = c.constraint_name
and b.constraint_name = d.r_constraint_name
and b.table_name='DEPT';



 create or replace view emprs as
   select deptno,count(*) rs
   from emp
   group by deptno;
不能通過視圖來改表
 update emprs set rs=10;
 update emprs set deptno=20;


 create or replace view emp_view as
   select ename,empno,sal from emp
   with read only;
--刪除視圖
 drop view emp_view;

 
<5>同義詞synonym
  設置權限的時候 有用
a)建立一個新的用戶mk  密碼m123;
  connect system/manager;
  create user mk identified by m123;
  grant connect,resource to mk;
b)登錄到用戶mk 建立一張表
  connect mk/m123;
  create table test(
    xh number(2) primary key,
    cname varchar2(10) not null);
  insert into test values (10,'Mike');
  commit;
c)希望在scott用戶下能看到mk用戶中test表的數據???
  connect mk/m123
  grant select on test to scott; //授權scott能select
  connect scott/tiger
  select * from mk.test;

  create synonym mtest for mk.test; //爲表建立的
                       //可以爲任何對象建立同義詞
  select * from mtest; //相當於select * from mk.test;
 
同義詞 增強數據庫的安全性
   connect mk/m123
   create sequence seq1;
   grant select on seq1 to scott;

   connect scott/tiger
   select mk.seq1.nextval from dual;

   爲序列建立一個同義詞
   create synonym seqa for mk.seq1;
   select seqa.nextval from dual;

a)某個用戶所擁有的同義詞都稱爲私有的同義詞,
別的用戶是不能使用它的
b)所有用戶都能使用的同義詞稱爲公有的同義詞public
只能定義在超級用戶下
 connect system/manager
 create public synonym ptest for mk.test;
 connect mk/m123
  select * from ptest;
   //同義詞只是個名字,到底能否查到數據取決於是否有權限
 
  取一個別名semp 相當於 scott.emp
  簡化名字,隱藏表的所有者
  增強安全性
 
  connect mk/m123;
 
  create synonym semp for scott.emp;

  select * from semp;
     --是否能查到數據
     --取決於是否有權限查詢


<6>索引
  作用:加快查詢  select
       索引一定是建立在表上的
  如何建立索引?

  a.有的建立表的時候的約束可以自動建索引
        primary key ------- 唯一性索引
        unique      ------- 唯一性索引

     create table t1(
       xh number(2) primary key,
       name varchar2(10) unique,
       age number(2)
);
 
  b.自己建索引
      加快查詢
      select * from t1 where age> 70;
      建立索引
      create index ind_t1_age on t1(age);
       //在表t1的age字段上建立索引ind_t1_age
     索引是自動維護的
        insert
        delete
        update 操作花費的時間變慢了
     一個表上的索引最好不要超過6個(有頻繁的增刪改操作的表)




      create index ind_t1_age1 on t1(age);
       
      create index ind_dept on dept(dname,loc);
      //聯合索引 分次序的
      create index ind_dept1 on dept(loc,dname);
 
      --刪除索引
      drop index ind_t1_age;
 
      create unique index ind_x on t1(age);
      //保證age的值唯一 (唯一性索引)

  <a>select語句是如何來使用索引的?
      select * from t1 ; --不能用索引,全表掃描
      select * from t1 where age > 20;
                    --能用age上的索引
      select * from t1 where name like '李%';
                    --能用上name上的索引
      select * from t1 where xh <45;
                    --能用上xh上的索引;

      select * from t1 where age > 20;
                   --能用索引
      select * from t1 where age+10>30;
                   --不能用age上的索引
                   --<1>規則1:索引的字段不能參與運算

      select * from t1 where substr(name,1,1)='李';
                     --不能用索引
                     --<2>規則2:索引的字段上不能使用函數
      select * from t1 where name like '李%';
                    --能用索引

  查詢emp表中hiredate在1982年10月到1999年9月的員工??

   select * from emp where to_char(hiredate,'yyyymm')
>= '198210' and to_char(hiredate,'yyyymm') <='199909';
  create index ind_hiredate on emp(hiredate);

                --用不上hiredate上的索引

   select * from emp where hiredate <= to_date('19990901','yyyymmdd')  and  
hiredate >= to_date('19821001','yyyymmdd');
                --能用上hiredate上的索引      


  察看索引的使用情況 看執行計劃
     執行計劃 -- 表示ORACLE是如何來執行你的select語句的

  對於複雜的查詢的效率 只能看執行計劃來確定
    關聯查詢
      select dname,ename from dept a,emp b
       where a.deptno = b.deptno;

 


     特殊索引
    <1> 位圖索引
      create bitmap index ind_aa on emp(job);
     數據的不同值對於記錄的行數來說 是個很小的數
     這種字段適合使用位圖索引
      select * from emp where job='CLERK';
      --用bitmap的索引 會比普通索引的效率要高

      create index ind_aa_c on emp(job);

    <2> 簇(cu)
      關聯查詢的時候,讓相關聯的字段在物理位置上放在  
     一起
    select dept.dname,empno,ename
   from dept , emp
   where dept.deptno = emp.deptno;

 --使dept的deptno字段和emp的deptno字段 在物理上放在    
    相鄰的位置上,這樣使得關聯查詢加快
   但是 會使得emp和dept的數據的插入變慢

如何建立簇
   --簇cluster
   --建立一個簇表
     --a)簇鍵
create cluster emp_dept(deptno_key number(2));

--b)建立表使用簇
create table emp1(empno number(4) primary key,
ename varchar2(10),
job varchar2(9),
mgr number(4),
hiredate date,
sal number(7,2),
comm number(7,2),
deptno number(2) references dept(deptno)
) cluster emp_dept(deptno);

create table dept1 (deptno number(2) primary key,
dname varchar2(14),
loc varchar2(10)) cluster emp_dept(deptno);

--c)建立簇表的索引
create index clu_emp_dept on cluster emp_dept;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章