(五)Oracle函数 序列 约束 索引
DECODE函數
DECODE函數基本語法
DECODE函數的語法如下:DECODE (expr, search1, result1[, search2, result2…][, default])
它用于比較參數expr的值,如果匹配到哪一個search條件,就返回對應的result結果,可以有多組search和result的對應關系,如果任何一個search條件都沒有匹配到,則返回最后default的值。default參數是可選的,如果沒有提供default參數值,當沒有匹配到時,將返回NULL。
查詢職員表,根據職員的職位計算獎勵金額,當職位分別是’MANAGER’、’ANALYST’、’SALESMAN’時,獎勵金額分別是薪水的1.2倍、1.1倍、1.05倍,如果不是這三個職位,則獎勵金額取薪水值:
SELECT ename, job, sal,DECODE(job, 'MANAGER', sal*1.2,'ANALYST', sal*1.1,'SALESMAN', sal*1.05, sal) AS bonus FROM emp;DECODE函數功能相似的有CASE語句,實現類似于if-else的操作。
SELECT ename, job, sal,CASE jobWHEN 'MANAGER' THEN sal * 1.2 WHEN 'ANALYST' THEN sal * 1.1 WHEN 'SALESMAN' THEN sal * 1.05 ELSE sal END bonus FROM emp;
排序函數
ROW_NUMBER
ROW_NUMBER語法如下:ROW_NUMBER() OVER(?PARTITION BY col1 ORDER BY col2)
表示根據col1分組,在分組內部根據col2排序。此函數計算的值就表示每組內部排序后的順序編號,組內連續且唯一。
ROWNUM是偽列, ROW_NUMBER功能更強,可以直接從結果集中取出子集。
場景:按照部門編碼分組顯示,每組內按職員編碼排序,并賦予組內編碼
SELECT deptno, ename, empno,ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY empno) AS emp_id FROM emp;RANK
RANK函數的語法如下:RANK() OVER(PARTITION BY col1 ORDER BY col2)
表示根據col1分組,在分組內部根據col2給予等級標識,即排名,相同的數據返回相同排名。特點是跳躍排序,如果有相同數據,則排名相同,比如并列第二,則兩行數據都標記為2,但下一位將是第四名。
和ROW_NUMBER的區別是有結果有重復值,而ROW_NUMBER沒有。
場景:按照部門編碼分組,同組內按薪水倒序排序,相同薪水則按獎金數正序排序,并給予組內等級,用Rank_ID表示
SELECT deptno, ename, sal, comm, RANK() OVER (PARTITION BY deptno ORDER BY sal DESC, comm) "Rank_ID" FROM emp;※PARTITION 分區
DENSE_RANK
DENSE_RANK函數的語法如下:?DENSE_RANK() OVER(?PARTITION BY col1 ORDER BY col2)
表示根據col1分組,在分組內部根據col2給予等級標識,即排名,相同的數據返回相同排名。特點是連續排序,如果有并列第二,下一個排序將是三,這一點是和RANK的不同,RANK是跳躍排序。
場景:關聯emp和dept表,按照部門編碼分組,每組內按照員工薪水排序,列出員工的部門名字、姓名和薪水:
SELECT d.dname, e.ename, e.sal, DENSE_RANK() OVER (PARTITION BY e.deptno ORDER BY e.sal) AS drank FROM emp e join dept d ON e.deptno = d.deptno;集合操作
UNION、UNION ALL
為了合并多個SELECT語句的結果,可以使用集合操作符,實現集合的并、交、差。
集合操作符包括UNION、UNION ALL、INTERSECT和MINUS。多條作集合操作的SELECT語句的列的個數和數據類型必須匹配。
ORDER BY子句只能放在最后的一個查詢語句中。
集合操作的語法如下:
SELECT statement1 [UNION | UNION ALL | INTERSECT | MINUS] SELECT statement2;UNION和UNION ALL用來獲取兩個或兩個以上結果集的并集:
- UNION操作符會自動去掉合并后的重復記錄。
- UNION ALL返回兩個結果集中的所有行,包括重復的行。
例如,合并職位是’MANAGER’的員工和薪水大于2500的員工集合,查看兩種方式的結果差別:
--Union SELECT ename, job, sal FROM emp WHERE job = 'MANAGER' Union SELECT ename, job, sal FROM emp WHERE sal> 2500;--Union all SELECT ename, job, sal FROM emp WHERE job = 'MANAGER' Union all SELECT ename, job, sal FROM emp WHERE sal> 2500;INTERSECT
INTERSECT函數獲得兩個結果集的交集,只有同時存在于兩個結果集中的數據,才被顯示輸出。使用INTERSECT操作符后的結果集會以第一列的數據作升序排列。
例如:顯示職位是’MANAGER’的員工和薪水大于2500的員工的交集:
SELECT ename, job, sal FROM emp WHERE job = 'MANAGER' INTERSECT SELECT ename, job, sal FROM emp WHERE sal> 2500;同理:
SELECT ename,job,sal FROM emp WHERE job = 'MANAGER' AND sal >2500;
MINUS
MINUS函數獲取兩個結果集的差集。只有在第一個結果集中存在,在第二個結果集中不存在的數據,才能夠被顯示出來。也就是結果集一減去結果集二的結果。
例如:列出職位是MANAGER但薪水低于2500的員工記錄:
SELECT ename, job, sal FROM emp WHERE job = 'MANAGER' MINUS SELECT ename, job, sal FROM emp WHERE sal > 2500;同理:
SELECT ename,job,sal FROM emp WHERE job = 'MANAGER' AND NOT sal > 2500;
主鍵約束
主鍵的意義
主鍵(Primary Key)約束條件從功能上看相當于非空(NOT NULL)且唯一(UNIQUE)的組合。主鍵字段可以是單字段或多字段組合,即:在主鍵約束下的單字段或者多字段組合上不允許有空值,也不允許有重復值。
主鍵可以用來在表中唯一的確定一行數據。一個表上只允許建立一個主鍵,而其它約束條件則沒有明確的個數限制。
主鍵選取的原則
- 主鍵應是對系統無意義的數據
- 永遠也不要更新主鍵,讓主鍵除了唯一標識一行之外,再無其他的用途
- 主鍵不應包含動態變化的數據,如時間戳
- 主鍵應自動生成,不要人為干預,以免使它帶有除了唯一標識一行以外的意義
- 主鍵盡量建立在單列上
添加主鍵約束
在建表時添加主鍵約束條件:
CREATE TABLE employees2 ( name VARCHAR2(30) constraint pk_name primary key, email VARCHAR2(50), salary NUMBER(7, 2), hiredate DATE );建表后創建主鍵約束條件,并自定義約束條件名稱:
CREATE TABLE employees3 ( eid NUMBER(6), name VARCHAR2(30), email VARCHAR2(50), salary NUMBER(7, 2), hiredate DATE );ALTER TABLE employees3 ADD CONSTRAINT employees3_eid_pk PRIMARY KEY (eid);/*查看表TEST的約束條件*/
SELECT * FROM all_constraints WHERE table_name = 'employees3';
外鍵約束
外鍵約束的意義
外鍵約束條件定義在兩個表的字段或一個表的兩個字段上,用于保證相關兩個字段的關系。比如emp表的deptno列參照dept表的deptno列,則dept稱作主表或父表,emp表稱作從表或子表。
添加外鍵約束
先建表,在建表后建立外鍵約束條件:
CREATE TABLE employees4 ( eid NUMBER(6), name VARCHAR2(30), salary NUMBER(7, 2), deptno NUMBER(4) );ALTER TABLE employees4 ADD CONSTRAINT employees4_deptno_fk FOREIGN KEY (deptno) REFERENCES dept(deptno);外鍵約束對一致性的維護
外鍵約束條件包括兩個方面的數據約束:
- 從表上定義的外鍵的列值,必須從主表被參照的列值中選取,或者為NULL;
- 當主表參照列的值被從表參照時,主表的該行記錄不允許被刪除。
外鍵約束對性能的降低
如果在一個頻繁DML操作的表上建立外鍵,每次DML操作,都將導致數據庫自動對外鍵所關聯的對應表做檢查,產生開銷,如果已在程序中控制邏輯,這些判斷將增加額外負擔,可以省去。
另外外鍵確定了主從表的先后生成關系,有時會影響業務邏輯。
關聯不一定需要外鍵約束
如果業務邏輯要求保證數據完整性,可由程序控制,不一定需要外鍵約束。
另外為了簡化開發,維護數據時不用考慮外鍵約束,以及大量數據DML操作時不需考慮外鍵耗費時間。
唯一性約束
什么是唯一性約束
唯一性(Unique)約束條件用于保證字段或者字段的組合不出現重復值。當給表的某個列定義了唯一約束條件,該列的值不允許重復,但允許是NULL值。
唯一性約束條件可以在建表同時建立,也可以在建表以后再建立。
添加唯一性約束
在建表employees的同時,在eid、email列上創建唯一約束條件,并在建表后在name列上建立一個名為employees_name_uk的唯一約束條件:
DROP TABLE employees ; --將表刪掉重新創建 CREATE TABLE employees (eid NUMBER(6) constraint employees_eid_uk unique,name VARCHAR2(30),email VARCHAR2(50),salary NUMBER(7, 2),hiredate DATE, );在建表之后增加唯一性約束條件:
ALTER TABLE employees ADD CONSTRAINT employees_name_uk UNIQUE(name);檢查約束
什么是檢查約束
檢查(Check)約束條件用來強制在字段上的每個值都要滿足Check中定義的條件。當定義了Check約束的列新增或修改數據時,數據必須符合Check約束中定義的條件。
添加檢查約束
員工的薪水必須大于2000元,增加檢查約束:
ALTER TABLE employees4 ADD CONSTRAINT employees4_salary_checkCHECK (salary > 2000);
當插入大于2000的數據,操作成功:
INSERT INTO employees4(eid, name, salary, deptno) VALUES(1236, 'donna noble', 2500, 40);試圖修改職員的薪水為1500元,更新失敗:
UPDATE employees4 SET salary = 1500 WHERE eid = 1236;?序列
什么是序列
序列(SEQUENCE)是一種用來生成唯一數字值的數據庫對象。序列的值由Oracle程序按遞增或遞減順序自動生成,通常用來自動產生表的主鍵值,是一種高效率獲得唯一鍵值的途徑。
序列是獨立的數據庫對象,和表是獨立的對象,序列并不依附于表。
通常情況下,一個序列為一個表提供主鍵值,但一個序列也可以為多個表提供主鍵值。
舉例說明,創建一個序列,起始數據是100,步進是10:
CREATE SEQUENCE emp_seq START WITH 100 INCREMENT BY 10;當序列被創建后,第一個序列值將是100,將要生成的序列號分別是110、120、130等。
序列中有兩個偽列:
- NEXTVAL:獲取序列的下個值
- CURRVAL:獲取序列的當前值
當序列創建以后,必須先執行一次NEXTVAL,之后才能使用CURRVAL。
獲取序列的第一個值,并且使用序列值為EMP表插入新的記錄:
SELECT emp_seq.NEXTVAL FROM DUAL; INSERT INTO emp(empno, ename) VALUES(emp_seq.NEXTVAL, 'donna');查詢剛剛生成的記錄,主鍵值將是110:
SELECT empno, ename FROM emp WHERE ename = 'DONNA';此時查詢序列的當前值,會得到110的數字。
SELECT emp_seq.CURRVAL FROM DUAL;在序列的使用過程中,比如執行了一條語句:
SELECT emp_seq.NEXTVAL FROM DUAL;則浪費了一個序列值,會導致表的主鍵值不連續。而CURRVAL的使用不會導致序列值的遞進。
刪除序列
刪除序列的語法如下:
DROP SEQUENCE sequence_name;刪除序列emp_seq:
DROP SEQUENCE emp_seq;索引
索引的原理
索引是一種允許直接訪問數據表中某一數據行的樹型結構,為了提高查詢效率而引入,是獨立于表的對象,可以存放在與表不同的表空間(TABLESPACE)中。索引記錄中存有索引關鍵字和指向表中數據的指針(地址)。對索引進行的I/O操作比對表進行操作要少很多。
索引一旦被建立就將被Oracle系統自動維護,查詢語句中不用指定使用哪個索引,是一種提高查詢效率的機制。
ROWID: 偽列,唯一標識一條數據記錄,可理解為行地址。
創建索引
創建索引的語法:
CREATE [UNIQUE] INDEX index_name ON table(column[, column…]);其中:
- index_name表示索引名稱
- table表示表名
- column表示列名,可以建立單列索引或復合索引
- UNIQUE表示唯一索引
在EMP表的ENAME列上建立索引:
CREATE INDEX idx_emp_ename ON emp(ename);復合索引也叫多列索引,是基于多個列的索引。如果經常在ORDER BY子句中使用job和salary作為排序依據,可以建立復合索引:
CREATE INDEX idx_emp_job_sal ON emp(job, sal);當做下面的查詢時,會自動應用索引idx_emp_job_sal
SELECT empno, ename, sal, job FROM emp ORDER BY job, sal;刪除索引
當一個表上有不合理的索引,會導致操作性能下降,刪除索引的語法:
DROP INDEX index_name;刪除索引idx_emp_ename:
DROP INDEX idx_emp_ename;合理使用索引提升查詢效率
為提升查詢效率,創建和使用索引的原則:
- 為經常出現在WHERE子句中的列創建索引
- 為經常出現在ORDER BY、DISTINCT后面的字段建立索引。如果建立的是復合索引,索引的字段順序要和這些關鍵字后面的字段順序一致
- 為經常作為表的連接條件的列上創建索引
- 不要在經常做DML操作的表上建立索引
- 不要在小表上建立索引
- 限制表上的索引數目,索引并不是越多越好
- 刪除很少被使用的、不合理的索引
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/Jonecmnn/p/6366327.html
總結
以上是生活随笔為你收集整理的(五)Oracle函数 序列 约束 索引的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UVA-804 模拟
- 下一篇: CFI Flash, SPI Flash