1. 程式人生 > 其它 >Oracle知識學習記錄(一)

Oracle知識學習記錄(一)

Oracle

1.Oracle簡介

1.1Oracle特點

  1. 支援多使用者,大事務量的事務處理
  2. 資料的安全性和完整性控制
  3. 支援分散式資料處理
  4. 可移植性

1.2Oracle體系結構

  1. 表空間

    圖1:

    圖2:

2.Oracle安裝和配置

2.1 VMware掛載windows2003

雙擊 windows2003中的 Windows Server 2003 Enterprise Edition.vmx

2.2 網路配置

外部虛擬網絡卡:192.168.80.6

虛擬機器內部:192.168.80.10

2.3 安裝Oracle資料庫

orcl /root

安裝成功後無圖形介面,可再cmd視窗輸入:sqlplus system/root 出現SQL> 代表連線資料庫成功

2.4 SqlPlus遠端連線Oracle資料庫

將instantclient_12_1放到D盤,在cmd視窗,進入D盤的instantclient_12_1目錄,輸入sqlplus system/[email protected]:1521/orcl

2.5 PLSQL安裝與配置

配置tnsnames.ora

配置環境變數:TNS_ADMIN

配置編碼集:


3.專案案例

3.1建立表空間,使用者,並賦予使用者許可權

--建立表空間
create tablespace waterboss
datafile 'c:\waterboss.dbf'
size 100m
autoextend on
next 10m;

--建立使用者
create user wateruser
identified by root--密碼
default tablespace waterboss;

--給wateruser賦予bda許可權
grant dba to wateruser;

4.建立表

資料型別:

  1. 字元型

(1)CHAR : 固定長度的字元型別,最多儲存 2000 個位元組

(2)VARCHAR2 :可變長度的字元型別,最多儲存 4000 個位元組

(3)LONG : 大文字型別。最大可以儲存 2 個 G

  1. 數值型

    ​ NUMBER : 數值型別

    ​ 例如:NUMBER(5) 最大可以存的數為 99999

    ​ NUMBER(5,2) 最大可以存的數為 999.99

  2. 日期型

    (1)DATE:日期時間型,精確到秒

    (2)TIMESTAMP:精確到秒的小數點後 9 位

  3. 二進位制型(大資料型別)

    (1)CLOB : 儲存字元,最大可以存 4 個 G

    (2)BLOB:儲存影象、聲音、視訊等二進位制資料,最多可以存 4 個 G

4.1建立業主表

--建立業主表
create table t_owners(
id number primary key,
name varchar2(30),
addressid number,
housenumber varchar2(30),
watermeter varchar2(30),
adddate date,
ownertypeid number
);

4.2修改表

4.2.1 增加欄位語法

ALTER TABLE 表名稱 ADD(列名 1 型別 [DEFAULT 預設值],列名 1 型別
[DEFAULT 預設值]...)
--追加欄位
ALTER TABLE T_OWNERS ADD
(
 REMARK VARCHAR2(20),
 OUTDATE DATE
)

4.2.2 修改欄位型別語法:

ALTER TABLE 表名稱 MODIFY(列名 1 型別 [DEFAULT 預設值],列名 1 型別
[DEFAULT 預設值]...)
--修改欄位型別
ALTER TABLE T_OWNERS MODIFY
(
REMARK CHAR(20),
OUTDATE TIMESTAMP
)

4.2.3 修改欄位名語法

ALTER TABLE 表名稱 RENAME COLUMN 原列名 TO 新列名
ALTER TABLE T_OWNERS RENAME COLUMN OUTDATE TO EXITDATE

4.2.4 刪除欄位名

--刪除一個欄位
ALTER TABLE 表名稱 DROP COLUMN 列名
--刪除多個欄位
ALTER TABLE 表名稱 DROP (列名 1,列名 2...)
--刪除欄位
ALTER TABLE T_OWNERS DROP COLUMN REMARK

4.3刪除表

DROP TABLE 表名稱

4.4增刪改資料

比較 truncate 與 delete 實現資料刪除?

  1. delete 刪除的資料可以 rollback
  2. delete 刪除可能產生碎片,並且不釋放空間
  3. truncate 是先摧毀表結構,再重構表結構

5.資料匯入匯出

5.1整庫匯入匯出

整庫匯出命令

exp system/root full=y -- 新增引數 full=y 就是整庫匯出  

執行命令後會在當前目錄下生成一個叫 EXPDAT.DMP,此檔案為備份檔案。 如果想指定備份檔案的名稱,則新增 file 引數即可,命令如下

exp system/root file=water.dmp(檔名) full=y

**整庫匯入命令 **

imp system/root full=y 

此命令如果不指定 file 引數,則預設用備份檔案 EXPDAT.DMP 進行匯入 如果指定 file 引數,則按照 file 指定的備份檔案進行恢復

imp system/root full=y file=water.dmp

5.2按使用者匯入匯出

按使用者匯出

exp system/root owner=wateruser file=wateruser.dmp

按使用者匯入

imp system/root file=wateruser.dmp fromuser=wateruser

5.3按表匯入匯出

按表匯出

exp wateruser/root file=a.dmp tables=t_account,a_area

用 tables 引數指定需要匯出的表,如果有多個表用逗號分割即可

按表匯出

imp wateruser/root file=a.dmp tables=t_account,a_area

6.sql語句

1.去重

--整條記錄去重
select distinct t.addressid,t.ownertypeid from t_owners t ;

2.偽劣

--偽劣 rowid(實體地址)
select rowid,t.* from t_owners t;
--偽劣 rownum(查詢記錄的行號)
select rownum,t.* from t_owners t where t.id>3;

3.聚合函式

--取和:sum()
select sum(a.usenum) from t_account a where a.year='2012';
--取平均值:avg()
select avg(a.usenum) from t_account a where a.year='2012';
--最大值
select max(a.usenum) from t_account a where a.year='2012';
--最小值
select min(a.usenum) from t_account a where a.year='2012';
--count
select count(1) from   t_account a where a.year='2012';
--分組
select a.areaid,sum(a.money) from t_account a  group by a.areaid;
--分組後條件查詢 having
select a.areaid,sum(a.money) from t_account a  group by a.areaid having sum(a.money)>169000;

4.連線查詢

4.1內連線

--內連線
select a.name 業主名,
       b.name 業主型別,
       c.name 地址,
       d.name 區域,
       e.name 收費員
  from t_owners a, t_ownertype b, t_address c, t_area d, t_operator e
 where a.ownertypeid = b.id
   and a.addressid = c.id
   and c.areaid = d.id
   and c.operatorid = e.id;

4.2左連線

--左連線(左表數全部展示出來,右表顯示空)
--sql1999語法
select ow.name, ac.year, ac.month, ac.money
  from t_owners ow left join t_account ac
 on ow.id = ac.owneruuid;
--oracle語法
select ow.name, ac.year, ac.month, ac.money
  from t_owners ow , t_account ac
 where ow.id = ac.owneruuid(+);

4.3右連線

--右連線(右表數全部展示出來,左表顯示空)
--sql1999語法
select ow.name, ac.year, ac.month, ac.money
  from t_owners ow right join t_account ac
 on ow.id = ac.owneruuid;
--oracle語法
select ow.name, ac.year, ac.month, ac.money
  from t_owners ow , t_account ac
 where ow.id(+) = ac.owneruuid;

5.子查詢

5.1where子查詢

  • 單行子查詢 (=,>)
  • 多行子查詢 (in)

5.2from子查詢

​ from 後面:查詢語句的查詢結果可作為一張表

5.3select子查詢

​ select查出的結果作為欄位值

6.分頁查詢

rownum:按行掃描,給出行號,一層查詢只能用<,<=

6.1簡單分頁

select * from (select rownum r, a.* from t_account a where a.year = '2012')
where r <= 20 and r > 10;--兩層查詢

6.2排序分頁

select *
  from (select rownum r, t.*
          from (select *
                  from t_account a
                 where a.year = '2012'
                 order by a.usenum desc) t)
 where r <= 20
   and r > 10;--三層查詢

7.單行函式

7.1字元函式

--字元函式
select length('asd') from dual ;--3
--substr 第2個引數:從下標開始擷取;第3個引數:擷取幾位
select substr('abcdef',2,4) from dual;--bcde 
select concat('ab','cd') from dual;--abcd
select 'a'||'b'||'c' from dual;--abc

7.2數值函式

--數值函式
--四捨五入,只有一個引數時四捨五入為整數
select round(100.456,2) from dual;--100.46
--擷取,只有一個引數時擷取到整數
select trunc(100.456,2) from dual;--100.45
--取模
select mod(10,3) from dual;--1

7.3日期函式

--日期函式
select sysdate from dual;--2021/10/18 17:32:27
--一個月後的日期
select add_months(sysdate,1) from dual;--2021/11/18 17:33:25
--月的最後一天
select last_day(sysdate) from dual;--2021/10/31 17:35:14
select last_day(sysdate-18) from dual;--2021/9/30 17:36:02
--擷取
select trunc(sysdate) from dual;--2021/10/18
--擷取到年(的第一天)
select trunc(sysdate,'yyyy') from dual;--2021/1/1
--擷取到月(的第一天)
select trunc(sysdate,'mm') from dual;--2021/10/1
--擷取到時
select trunc(sysdate,'hh') from dual;--2021/10/18 17:00:0
--擷取到分
select trunc(sysdate,'mi') from dual;--2021/10/18 17:37:00

7.4轉換函式

--轉換函式
--to_char 數字轉字串
select to_char(100) from dual;
--to_char 日期轉字串
select sysdate from dual;--2021/10/18 17:54:53
select to_char(sysdate,'yyyy-mm-dd HH:mi:ss') from dual;--2021-10-18 05:55:40
--to_date 字串轉日期
select to_date('2020-10-10','yyyy-mm-dd') from dual;--2020/10/10
select to_date('20201010','yyyymmdd') from dual;--2020/10/10
--to_number 字串轉數字
select to_number('200') from dual;

7.5其他函式

--其他函式
--nvl(param1,param2)如果第一個引數是null,返回第二個引數,否則返回第一個引數
select nvl(null,0) from dual;--0
select nvl(100,0) from dual;--100
--nvl2(param1,param2,param3)如果第一個引數是null,返回第三個引數,否則返回第二個引數
select nvl2(200,100,0) from dual;--100
select nvl2(null,100,0) from dual;--0

select nvl2(a.maxnum,to_char(maxnum),'上限') from t_pricetable a where a.ownertypeid='1';

--decode
select a.name,
       a.ownertypeid,
       decode(a.ownertypeid, 1, '居民', 2, '行政單位', 3, '商業','其他')
  from t_owners a;
 --case when then else end 
select a.name,
       a.ownertypeid,
       case a.ownertypeid
            when 1 then
             '居民'
            when 2 then
             '行政單位'
            when 3 then
             '商業'
            else
             '其他'
       end
  from t_owners a;

8.行列轉換

--行列轉換
select  (select b.name from t_area b where b.id=a.areaid) 區域,
sum(case when a.month='01'  then money else 0 end ) 一月,
sum(case when a.month='02'  then money else 0 end ) 二月,
sum(case when a.month='03'  then money else 0 end ) 三月,
sum(case when a.month='04'  then money else 0 end ) 四月,
sum(case when a.month='05'  then money else 0 end ) 五月,
sum(case when a.month='06'  then money else 0 end ) 六月,
sum(case when a.month='07'  then money else 0 end ) 七月,
sum(case when a.month='08'  then money else 0 end ) 八月,
sum(case when a.month='09'  then money else 0 end ) 九月,
sum(case when a.month='10'  then money else 0 end ) 十月,
sum(case when a.month='11'  then money else 0 end ) 十一月,
sum(case when a.month='12'  then money else 0 end ) 十二月
  from t_account a
 where a.year = '2012' group by a.areaid;
--行列轉換
select  (select b.name from t_area b where b.id=a.areaid) 區域,
sum(case when a.month>='01' and a.month<='03'  then money else 0 end ) 第一季度,
sum(case when a.month>='04' and a.month<='06'  then money else 0 end ) 第二季度,
sum(case when a.month>='07' and a.month<='09'  then money else 0 end ) 第三季度,
sum(case when a.month>='10' and a.month<='12'  then money else 0 end ) 第四季度
  from t_account a
 where a.year = '2012' group by a.areaid;
 --decode
 select  (select b.name from t_area b where b.id=a.areaid) 區域,
sum(decode (a.month,01,money,02,money,03,money,  0  )) 第一季度,
sum(decode (a.month,04,money,05,money,06,money,  0  )) 第二季度,
sum(decode (a.month,07,money,08,money,09,money,  0  )) 第三季度,
sum(decode (a.month,10,money,11,money,12,money,  0  )) 第四季度
  from t_account a
 where a.year = '2012' group by a.areaid;

9.分析函式

--分析函式
--rank() 值相同,排名相同,排名跳躍
select rank() over(order by t.usenum desc) 排名, t.* from t_account t ;
--dense_rank( )值相同,排名相同,排名連續
select dense_rank() over(order by t.usenum desc) 排名, t.* from t_account t ;
--row_number() 值相同,排名連續
select row_number() over(order by t.usenum desc) 排名, t.* from t_account t ;
--row_number() 分頁(由rownum的三層查詢變為兩層)
select * from(
select row_number() over(order by t.usenum desc) r, t.* from t_account t)
where r<=20 and r>10;

10.集合運算

--集合運算
--union 去重
select * from t_owners t where t.id <8
union 
select * from t_owners t where t.id >5;
--union all 有重複記錄
select * from t_owners t where t.id <8
union all
select * from t_owners t where t.id >5;
--intersect 交集
select * from t_owners t where t.id <8
intersect
select * from t_owners t where t.id >5;
--minus 差集
select * from t_owners t where t.id <8
minus
select * from t_owners t where t.id >5;

7.檢視

檢視是一個虛表,可以將多表查詢sql定義為一個檢視

使用檢視的優點:

  1. 簡化資料操作:檢視可以簡化使用者處理資料的方式。
  2. 著重於特定資料:不必要的資料或敏感資料可以不出現在檢視中。
  3. 檢視提供了一個簡單而有效的安全機制,可以定製不同使用者對資料的訪問 許可權。
  4. 提供向後相容性:檢視使使用者能夠在表的架構更改時為表建立向後相容接 口。

7.1檢視語法

建立檢視:

CREATE [OR REPLACE] [FORCE] VIEW view_name 
AS subquery 
[WITH CHECK OPTION ] 
[WITH READ ONLY]

OR REPLACE :若所建立的試圖已經存在,ORACLE 自動重建該檢視;

FORCE :不管基表是否存在 ORACLE 都會自動建立該檢視;

subquery :一條完整的 SELECT 語句,可以在該語句中定義別名;

WITH CHECK OPTION :插入或修改的資料行必須滿足檢視定義的約束;

WITH READ ONLY :該檢視上不能進行任何 DML 操作。

刪除檢視:

DROP VIEW view_name

7.2建立簡單檢視

--建立檢視 :業主型別為 1 的業主資訊
create or replace view view_owners1 as
select * from t_owners a where a.ownertypeid='1';

總結:檢視是虛表,存放的是sql語句並非資料,對檢視的操作就是對錶的操作,修改檢視後表的資料會跟著變,修改表資料後檢視資料也會變

7.3帶檢查約束的檢視

--根據地址表(T_ADDRESS)建立檢視 VIEW_ADDRESS2 ,內容為區域 ID為 2 的記錄。
create or replace view view_address2 as
select * from t_address a where a.areaid='2'
with check option;
--錯誤語法,with check option不能修改檢視中的條件的值
update view_address2 a set a.AREAID='3' where a.ID='3';

7.4只讀檢視

--建立只讀檢視 :業主型別為 1 的業主資訊
create or replace view view_owners1 as
select * from t_owners a where a.ownertypeid='1'
with read only;
--只讀檢視不能修改,會報錯
update view_owners1 a set a.NAME='範小冰' where a.ID='1';

7.5建立帶錯誤的檢視

--建立帶錯誤的檢視
create force view view_test as 
select * from test;

7.6複雜檢視(多表查詢)

--複雜檢視(多表關聯)
--建立檢視,查詢顯示業主編號,業主名稱,業主型別名稱
create or replace view view_owners as
select o.id 業主編號,o.name 業主名稱,ot.name 業主型別名稱
 from t_owners o,t_ownertype ot where o.ownertypeid=ot.id;

--修改成功
update view_owners a set a.業主名稱='範小冰' where a.業主編號='1';

--修改失敗(錯誤原因見下圖),只有鍵保留表的列才可修改
update view_owners a set a.業主型別名稱='業主' where a.業主編號='1';

鍵保留表:

一個表的主鍵在檢視中也是主鍵,則這個表是鍵保留表

在我們這個例子中,檢視中存在兩個表,業主表(T_OWNERS)和業主型別表 (T_OWNERTYPE), 其中 T_OWNERS 表就是鍵保留表,因為 T_OWNERS 的 主鍵也是作為檢視的主鍵。鍵保留表的欄位是可以更新的,而非鍵保留表是不能 更新的。

7.7複雜檢視(聚合函式)

--複雜檢視(聚合函式)
--建立檢視,按年月統計水費金額
create view view_accoutsum as
select a.year, a.month, sum(a.money) money
  from t_account a
 group by a.year, a.month
 order by a.year, a.month;
 --此例用到聚合函式,沒有鍵保留表,無法執行 update 。
update view_accoutsum a set a.money='10000' 
where a.year='2012' and a.month='03' ;

8.物化檢視

8.1什麼是物化檢視

  • 檢視是一個虛擬的表,存放的sql語句;物化檢視類似於實體表,會存放具體的資料。

  • 物化檢視與普通的檢視相比的區別是物化檢視是建立的副本,它類似於一張 表,需要佔用儲存空間。而對一個物化檢視查詢的執行效率與查詢一個表是一樣 的。

  • 檢視不佔儲存空間,查詢慢;物化檢視佔儲存空間,查詢快

8.2物化檢視的語法

CREATE METERIALIZED VIEW view_name
[BUILD IMMEDIATE | BUILD DEFERRED ]
REFRESH [FAST|COMPLETE|FORCE]
[
ON [COMMIT |DEMAND ] | START WITH (start_time) NEXT
(next_time)
]
AS
subquery
  1. BUILD IMMEDIATE 是在建立物化檢視的時候就生成資料

BUILD DEFERRED 則在建立時不生成資料,以後根據需要再生成資料

預設為 BUILD IMMEDIATE。

  1. 重新整理(REFRESH):指當基表發生了 DML 操作後,物化檢視何時採用哪種 方式和基表進行同步。

​ REFRESH 後跟著指定的重新整理方法有三種:FAST、COMPLETE、FORCE。

FAST 重新整理採用增量重新整理,只重新整理自上次重新整理以後進行的修改。

COMPLETE 重新整理對整 個物化檢視進行完全的重新整理。

​ 如果選擇 FORCE 方式,則 Oracle 在重新整理時會去判 斷是否可以進行快速重新整理,如果可以則採用 FAST 方式,

​ 否則採用 COMPLETE 的方式。

FORCE 是預設的方式。

  1. 重新整理的模式有兩種:ON DEMAND 和 ON COMMIT。

    ON DEMAND 指需要 手動重新整理物化檢視(預設)。

    ON COMMIT 指在基表發生 COMMIT 操作時自動 重新整理。

8.3建立手動重新整理的物化檢視

--建立手動重新整理的物化檢視
--需求:查詢地址 ID,地址名稱和所屬區域名稱
create materialized view mv_address as 
select ad.id,ad.name,ar.name arname 
from t_address ad,t_area ar 
where ad.areaid=ar.id;
--查詢物化檢視
select * from mv_address;
--這時,我們向基表地址表(T_ADDRESS)中插入一條新記錄
insert into t_address values(8,'西三旗',2,2);
commit;
--插入後查詢基表t_address,發現多了一條記錄
select * from t_address;
--查詢物化檢視mv_address,發現沒有新增記錄,因為預設是手動重新整理
select * from mv_address;
--需要通過下面的語句(PL/SQL),手動重新整理物化檢視
Begin
     DBMS_MVIEW.refresh('MV_ADDRESS','C');
END;
--或者在命令視窗通過下面的命令手動重新整理物化檢視:
SQL> EXEC DBMS_MVIEW.refresh('mv_address','C')
PL/SQL procedure successfully completed
--執行完後發現物化檢視多了一條記錄

8.4建立自動重新整理的物化檢視

--建立自動重新整理的物化檢視
--需求:查詢地址 ID,地址名稱和所屬區域名稱
create materialized view mv_address2 
refresh
on commit
as
select ad.id,ad.name,ar.name arname
from t_address ad,t_area ar
where ad.areaid=ar.id;

--這時,我們向基表地址表(T_ADDRESS)中插入一條新記錄
insert into t_address values(10,'西五旗',2,2);

--查詢物化檢視,發現多了一條記錄
select * from mv_address2;

8.5 建立時不生成資料的物化檢視

--建立時不生成資料的物化檢視
create materialized view mv_address3 
build deferred
refresh
on commit
as
select ad.id,ad.name,ar.name arname
from t_address ad,t_area ar
where ad.areaid=ar.id;

--這時,我們向基表地址表(T_ADDRESS)中插入一條新記錄
insert into t_address values(11,'西六旗',2,2);
commit;
--查詢物化檢視,發現沒有記錄
select * from mv_address3;
--第一次時,手動重新整理資料,以後會自動重新整理
begin
     dbms_mview.refresh('mv_address3','C');
end;
--這時,我們再向基表地址表(T_ADDRESS)中插入一條新記錄
insert into t_address values(12,'西七旗',2,2);
commit;
--再次查詢物化檢視,發現自動新增一條西七旗記錄
select * from mv_address3;

8.6 建立增量重新整理的物化檢視

--4.建立增量重新整理的物化檢視
--建立增量重新整理的物化檢視前提1:
--建立基表的日誌(建立的物化檢視日誌名稱為 MLOG$_表名稱)
create materialized view log on t_address with rowid;
create materialized view log on t_area with rowid;
----建立增量重新整理的物化檢視前提2:列出rowid
create materialized view mv_address4 
refresh fast
as
select ad.rowid adrowid,ar.rowid arrowid,ad.id,ad.name,ar.name arname
from t_address ad,t_area ar
where ad.areaid=ar.id;

--查詢物化檢視,共12條資料
select * from mv_address4;

--這時,我們向基表地址表(T_ADDRESS)中插入一條新記錄
insert into t_address values(13,'西八旗',2,2);
commit;
--這時,我們向基表地址表(T_ADDRESS)中插入一條新記錄
insert into t_address values(14,'西九旗',2,2);
commit;
--這時,刪除id是13的資料
delete from t_address where id=13;
commit;

--觀察日誌表(見下圖),日誌表的資料在重新整理後會刪除

--手動重新整理
begin
     dbms_mview.refresh('MV_ADDRESS4','C');
END;

--再次查詢物化檢視,發現已新增id為14的資料
select * from mv_address4;

日誌表截圖如下:

SNAPTIME$$:用於表示重新整理時間。

DMLTYPE$$:用於表示 DML 操作型別,I 表示 INSERT,D 表示 DELETE,U 表示 UPDATE。

OLD_NEW$$:用於表示這個值是新值還是舊值。N(EW)表示新值,O(LD) 表示舊值,U 表示 UPDATE 操作。

CHANGE_VECTOR$$:表示修改向量,用來表示被修改的是哪個或哪幾個欄位。 此列是 RAW 型別,其實 Oracle 採用的方式就是用每個 BIT 位去對映一個列。 插入操作顯示為:FE, 刪除顯示為:OO 更新操作則根據更新欄位的位置而顯示 不同的值。

9.序列

9.1 什麼是序列

​ Oracle提供的用於產生一系列唯一數字的資料庫物件

9.2 建立與使用簡單序列

通過序列的偽列來訪問序列的值 :

NEXTVAL 返回序列的下一個值

CURRVAL 返回序列的當前值

--建立簡單序列
create sequence test;
--查詢下一個序列
select test.nextval from dual;
--查詢當前序列
select test.currval from dual;

注意:我們在剛建立序列後,無法提取當前值,只有先提取下一個值時才能再次 提取當前值。

9.3 建立複雜序列語法

CREATE SEQUENCE sequence //建立序列名稱
[INCREMENT BY n] //遞增的序列值是 n 如果 n 是正數就遞增,如果是負數就遞減 默
認是 1
[START WITH n] //開始的值,遞增預設是 minvalue 遞減是 maxvalue
[{MAXVALUE n | NOMAXVALUE}] //最大值
[{MINVALUE n | NOMINVALUE}] //最小值
[{CYCLE | NOCYCLE}] //迴圈/不迴圈
[{CACHE n | NOCACHE}];//分配並存入到記憶體中

9.4 複雜序列--有最大值的非迴圈序列

--複雜序列-有最大值的非迴圈序列  
create sequence seq_test
increment by 5
start with 5
minvalue 1
maxvalue 20;
select seq_test.nextval from dual
結果:5,10,15,20

注意: 開始值不能小於最小值 ;序列超過maxvalue會報錯

9.4 複雜序列--有最大值的迴圈序列

--複雜序列-有最大值的迴圈序列  
create sequence seq_test2
increment by 1
start with 5
minvalue 1
maxvalue 25
cycle;
select seq_test2.nextval from dual;
結果:5,6,...24,25,1,2,...24,25,1,2,...24,25...

**注意:迴圈的序列,第一次迴圈是從開始值開始迴圈,而第二次循 環是從最小值開始迴圈。 **

9.4 複雜序列--帶快取的序列

--複雜序列--帶快取的序列
create sequence seq_test3
increment by 10
start with 10
minvalue 10
maxvalue 100
cycle
cache 10;

執行報錯:

上邊錯誤提示的意思是:快取設定的數必須小於每次迴圈的數。

我們的 cache 是 10,每次增長值是 10。這樣 10 次快取提取出 的數是 100 (10*10)

minvalue是10,maxvalue是100時,之間的數為90個; 把最小值減 1,或把最大值加 1,都可以通過。

--複雜序列--帶快取的序列
create sequence seq_test3
increment by 10
start with 10
minvalue 10
maxvalue 101--修改為101
cycle
cache 10;
select seq_test3.nextval from dual;
結果:10,20,30,...100,10,20,30,...100...

9.5 修改和刪除序列

--修改序列(不能更改序列的 START  WITH 引數 )
--語法:ALTER SEQUENCE 序列名稱 MAXVALUE 5000 CYCLE;
alter sequence seq_test3 maxvalue 102;

--刪除序列
--語法: DROP SEQUENCE 序列名稱;  
drop sequence test;

10.同義詞

同義詞是基物件的一個別名,包含公共同義詞( PUBLIC修飾)和私有同義詞 。

公共同義詞:資料庫的所有使用者都能訪問;

私有同義詞: 只允許特定使用者或有基物件訪問許可權的使用者進行訪問

10.1 建立與使用同義詞 語法

create [public]  synonym 同義詞名  for object;

object 表示表,檢視,序列等我們要 建立同義詞的物件的名稱。

10.2 私有同義詞

--私有同義詞
create synonym owner for t_owners;
--通過同義詞查詢t_owners
select * from owner;

私有同義詞只有當前使用者可以使用

10.3公有同義詞

--公有同義詞
create public  synonym owner2 for t_owners;
--通過同義詞查詢t_owners
select * from owner2;

公有同義詞所有使用者可以使用

11.索引

11.1什麼是索引

  • 索引是加速資料存取的資料物件
  • 使用索引可以提高查詢效能
  • 索引會佔儲存空間

11.2普通索引語法

create index 索引名稱 on 表名(列名);

11.3建立普通索引

--我們經常要根據業主名稱搜尋業主資訊,所以我們基於業主表的 name 欄位來建立索引
create index index_owners_name on t_owners(name);

11.4 索引效能測試

--索引效能測試
--建立一個兩個欄位的表
create table indextest(
id number,
name varchar2(30)
);
select * from indextest;
--編寫 PL/SQL 插入100萬條資料
begin
    for x in 1..1000000
    loop
          insert into indextest values(x,'AA'||x);    
    end loop
    commit;
end;
--根據 name 列建立索引
create index index_test_name on indextest(name);

--用id和name查詢同一條記錄,觀察查詢時間
select * from indextest a where a.id='765432';--最小時間0.047
select * from indextest a where a.name='AA765432';--最小時間0.015
--用name索引查詢快於用id查詢

11.5唯一索引

如果需要在某個表某個列建立索引,而這列的值是不會重複的。這時我們可 以建立唯一索引

唯一索引語法:

create unique index 索引名稱 on 表名(列名);
--在業主表的水錶編號一列建立唯一索引
create unique index index_owners_meter on t_owners(watermeter);

11.6複合索引

  • 對多個列建立複合索引
--語法:
create index 索引名稱 on 表名(列名,列名.....);
--複合索引-根據地址和門牌號對業主表建立索引
create index index_owners_ah on t_owners(addressid,housenumber);

11.7反向鍵索引

應用場景:

當某個欄位的值為連續增長的值,如果構建標準索引,會形成歪脖子樹。這樣會增加查詢的層數,效能會下降。建立反向鍵索引,可以使索引的值變 得不規則,從而使索引樹能夠均勻分佈。

--語法:
create index 索引名稱 on 表名(列名) reverse;

11.8點陣圖索引

  • 使用場景:點陣圖索引適合建立在低基數列

  • 點陣圖索引不直接儲存 ROWID,而是儲存位元組位到 ROWID 的對映

  • 優點:減少響應時間,節省空間佔用

--語法:
create bitmap index 索引名稱 on 表名(列名);
--我們在 T_owners 表的 ownertypeid 列上建立點陣圖索引,
create bitmap index index_owners_ownertypeid on t_owners(ownertypeid);