一、數據更新操作
DML語法中主要包括兩個內容:查詢與更新,更新主要包括:增加數據、修改數據、刪除數據。其中這些操作是離不開查詢的。
1、增加數據
語法:INSERT INTO 表名稱 [(字段名稱1, 字段名稱2,…)] VALUES(數據1,數據2…..);
注意:
1、對於字符串需要使用""括起來
2、對於時間可以使用to_date()進行轉換
3、數字就直接寫
范例:向myemp表中插入一條數據
INSERT INTO myemp(empno, job, sal, hiredate, ename, deptno, mgr,comm)
VALUES(6666,'清潔工',2000, TO_DATE('1988-10-10','yyyy-mm-dd'),'王二',40,7369,null);
2、修改數據
語法:UPDATE 表名稱 SET 字段1=內容1,字段2=內容2,..…[WHERE 更新條件(s)]
范例:要求將雇員編碼為7369的雇員,工資修改為810、佣金改為100
UPDATE myemp SET sal=810,comm=100 WHERE empno=7369;
范例:將所有在81年雇佣的雇員的雇佣日期修改為今天,工資增長20%
UPDATE myemp SET hiredate=SYSDATE, sal=sal*1.2
WHERE hiredate BETWEEN '01-1月-1081' AND '31-12月-1981';
3、刪除數據
語法:DELETE FROM 表名稱 [WHERE 刪除條件(s)];
范例:刪除雇員編號為7369的雇員信息
DELETE FROM myemp WHERE empno=7369;
范例:刪除幾個員工的信息(用IN)
DELETE FROM myemp WHERE empno IN (7566,7788,7899);
二、事物的處理
1、事務的概念
事物:是保證數據完整性的一種手段。事物具備ACID原則,保證一個人更新數據的時候,其他人不能更新。
2、事務鎖的概念
事務處理的兩個核心命令:
提交事物:commit;
回滾事物:rollback;
真正使用了commit提交的時候才表示更新是可以正常完成的。所有的更新操作都需要被事務所保護。
事務鎖:每一個session都有自己進行的事務處理。如果兩個不同的session更新了同一個數據,在一個session未更新完成之前,另一個session是不能進行更新操作的。這個過程就叫做事務鎖:在提交或回滾更新之前,只能有一個session能夠對數據進行操作,實現了事物的隔離性
3、事務處理的思想
案例:如果突然需要對所有用戶的某一個字段的內容進行更新,在用戶數據量足夠大的情況下,那么這樣就會出現一個問題:
如果直接更新,那么數據量足夠大的情況下,需要的時間也是非常長的,且在更新的時間段,所有的用戶不能登錄系統做其他的操作,相當於系統癱瘓。這種做法是拿時間換空間
如果換一種做法:用空間來換時間:將客戶分為活躍用戶與非活躍用戶,優先更新活躍用戶的信息,或者在用戶進行登錄的時間進行用戶操作,這是一個周期完成的事情,並不是一下子完成的。
所謂的解決方法都是取決於時間復雜度或者空間復雜度,要不就是拿時間換空間,要不就是拿空間換時間,具體的做法還需結合具體的情況進行分析,但是這是一個最基本的想法。
三、數據偽列
1、行號
行號是自動生成的,但是他是動態的,並不會特定的指定某些行,他是根據你查詢出來的數據進行自動行生成的。
范例:SELECT ROWNUM, empno, ename, job FROM emp;
rownum的作用:
1、取得第一行的數據
2、取得前N行的數據
注意:rownum不能直接取得后幾行或者中間部分的數據
1、取得第一行的數據一般是用來取得表的數據結構,一般在實際的操作中,我們不會使用查詢全部的語句進行操作:select * from 表名。
SELECT * FROM emp WHERE ROWNUM=1;
2、實現上下翻頁顯示
CurrentPage,表示的是當前所在頁;
LineSize,表示每頁顯示的數據行;
語法:
SELECT *
FROM(
SELECT ROWNUM rn, 列.... FROM 表名稱
WHERE ROWNUM <= currentPage*lineSize) temp
WHERE temp.rn>(currentPage-1)*lineSize;
3、行ID
所謂的ROWID指的是針對每行數據提供的物理地址。
以”AAAR3qAAEAAAACHAAA"這個數據為例,ROWID組成:
數據對象編號:AAAR3q
數據文件編號:AAE
數據保存的塊號:AAAACH
數據保存的行號:AAA
面試題:表中有許多完全重復的數據,要求將重復的數據刪除掉(只剩最后一個);
分析:
表中的數據列信息幾乎都是一樣的,所以如果按照已有的字段刪除,那么最終的結果都會被刪除掉。
那么現在即便數據重復了,在Oracle里面存在一個ROWID,它的物理保存地址也是不可能一樣的。
在程序之中都會設計累加的操作,所以理論上來講,最早保存數據的ROWID的內容應該是最小的。如果要想確認最小,利用MIN()函數完成。
現在mydept表中的數據又重復,那么可以采用分組,按照重復內容分組之后統計出最小的ROWID(最早的ROWID)。
第一步:查找出最小的rowid的數據
SELECT deptno, dname, loc, MIN(ROWID)
FROM mydept
GROUP BY deptno, dname, loc;
第二步:刪除rowid不在這其中的數據
DELETE FROM mydept WHERE ROWID NOT IN(
SELECT MIN(ROWID)
FROM mydept
GROUP BY deptno, dname, loc);
四、表的創建與管理
1、常用的數據類型
1、字符串:使用VARCHAR2描述(其他數據庫使用VARCHAR),200個字以內的都使用此類型,例如:姓名、地址、郵政編碼、電話、性別;
2、數字:在Oracle之中使用NUMBER來描述數字,如果描述小數使用“NUMBER(m,n)”,其中n位為小數位,而m-n為整數位,但是數據庫也考慮了程序人員的習慣;
-整數,使用INT;
-小數,使用FLOAT。
3、日期:使用DATE是最為常見的做法,但是在Oracle里面DATE里面包含有日期時間,可是其他的數據庫里面DATE可能只是日期,DATETIME才是表示日期時間;
4、大本文數據:使用CLOB描述,最多可以保持4G的文字信息;
5、大對象數據:使用BLOB,保持圖片、音樂、電影,文字,最多可以保持4G。
從實際的開發來說就使用VARCHAR2、NUMBER、DATE、CLOB。
2、表的創建
語法:
CREATE TABLE 表名稱 (
列名稱 類型 [DEFAULT 默認值],
列名稱 類型 [DEFAULT 默認值],
列名稱 類型 [DEFAULT 默認值],
....
列名稱 類型 [DEFAULT 默認值]
);
范例:創建一張名為member的表,他有四個描述:mid、name、birthday、note
CREATE TABLE member(
mid NUMBER ,
name VARCHAR2(20) DEFAULT '無名氏' ,
birethday DATE DEFAULT SYSDATE,
note CLOB
);
向表中插入數據:
INSERT INTO member(mid,name,birethday,note)
VALUES (1,'張三',TO_DATE('1890-10-10','yyyy-mm-dd'),'網數據線');
3、表的基本操作:表復制、表刪除、閃回技術
復制表:
CREATE TABLE 表名稱AS 子查詢;
可以將查詢出來的子表作為一張表的形式復制給一個新的表格保存下來
范例:將所有30部門雇員信息保存在emp30表中
CREATE TABLE emp30 AS SELECT * FROM emp WHERE deptno=30;
刪除表:
在正常的情況下,數據表一旦被刪除了,是無法恢復的,請慎用:
DROP TABLE 表名;
范例:刪除數據表
DROP TABLE dept;
閃回技術:
FlashBack的功能給予了用戶的后悔機會,但是現在如果用戶想要去操作這個回收站,那么用戶而言具備查看、恢復、情況、徹底刪除幾項操作。
1、刪除數據表之后查看回收站:
SHOW RECYCBLEBIN;
2、恢復刪除的表
FLASHBACK TABLE 表名 TO BEFORE DROP;
徹底刪除表格操作:
1、徹底刪除person表
DROP TABLE person PURGE;
2、清空回收站
PURGE RECYCLEBIN;
4、恢復表的腳本
這個腳本可以對數據庫進行快速的恢復。該腳本包含有如下的幾個內容:
1、刪除原有的數據表;
2、重新創建新的數據表;
3、創建測試數據;
4、進行提交。
代碼實現:
--刪除數據表
DROP TABLE member PURGE;
--情況回收站
PURGE RECYCLEBIN;
--創建數據表
CREATE TABLE member(
mid NUMBER,
name VARCHAR2(20)
);
--測試數據
INSERT INTO member(mid, name) VALUES (1, '張三');
INSERT INTO member(mid, name) VALUES (2, '李四');
--提交事物
COMMIT;
五、約束的創建與管理
1、數據的條件
為了保證數據表中的數據的完整性,數據需要滿足若干條件后才可以進行操作,約束是一把雙刃劍,約束的確會保證數據的合法性后才進行保存,如果在一張表中有過多的約束的話,那么更新的速度就一定會慢,在開發過程中,有些驗證的操作(約束)可以在程序中完成:
六種約束:
數據類型
非空約束
唯一約束
主鍵約束
檢查約束
外鍵約束
2、非空約束
非空約束:指表中的某一字段的內容不允許為空,如果使用非空的約束,只需要在某列的后面,利用NOT NULL 聲明就可以了。
在創建表的時候,在該列的后面添加not null聲明
create table member (
id number ,
name varchar2(15) default '無名氏' NOT NULL,
sex varchar2(5),
bithday date default sysdate
); ---表示name的字段這塊不允許為空
3、唯一約束
唯一約束:在某一列的內容不能出現重復的情況,如身份證、郵箱等,設置唯一約束只需要在該列后面添加 unique 字段即可
create table member (
id number ,
name varchar2(15) default '無名氏' NOT NULL,
email varchar2(5) UNIQUE,
bithday date default sysdate
); ---表示email 字段的內容必須為唯一的,不可以出現重復的信息
注意:在唯一性約束出錯的時候,不會像非空約束那樣直接給出是哪列的數據出現了問題,在實際開發中,可使用簡寫的方式,對於出錯信息進行提示,以方便修改:
在創建約束的時候,使用簡寫 約束名稱_字段 的形式進行顯示:
CONSTRAINT uk_email UNIQUE(email)
create table member (
id number ,
name varchar2(15) default '無名氏' NOT NULL,
email varchar2(5) ,
bithday date default sysdate,
CONSTRAINT uk_email UNIQUE(email)
); ---使用uk_email 的簡寫方式,可以在錯誤的時候進行簡單的提示,可以快速的捕捉到問題列
注意2:null不在唯一約束的判斷范圍之內
4、主鍵約束(primary key ,pk)
主鍵約束= 非空約束+唯一約束;設置為主鍵的列,既不能為空也不能出現重復的數據
定義主鍵約束:
create table member (
id number ,
name varchar2(15) default '無名氏' NOT NULL,
CONSTRAINT pk_id primary key(id)
);----實現主鍵約束,請使用簡寫的方式
5、檢查約束 :check 、ck
在數據列生設置一些過濾條件,當過濾條件滿足時才可以進行操作
如年齡的設置:年齡范圍0-120
設置檢查約束:
create table member (
id number ,
name varchar2(15) default '無名氏' NOT NULL,
age number(3),
CONSTRAINT ck_age check(age between 0 and 120)
);---實現列的條件約束
6、外鍵約束 (foreign ,fk)
作用:在兩張表有關聯的時候,比如父表與字表的關聯時,必須設置關聯字段的關系,否則會導致在父表中不存在的數據,在子表中也是可以同樣插入的
create table member(
mid number,
name varchar2(20),
constraint pk_mid primary key(mid) ----設置主鍵
)
create table book(
bid number,
title varchar2(20),
mid number
constraint fk_mid foreign key(mid) references member(mid) on delete cascade ----設置book中的mid為外鍵,且數據來源於member表中的mid
)----on delete cascad 是設置級聯刪除
注意:外鍵的限制
1、在刪除父表之前,要先刪除掉她的對應的全部的子表之后才可以進行刪除
強制刪除父表的操作,不關心子表是否存在:drop table 表名稱 cascade constraint ---盡量不要使用強制刪除,盡量使用先刪除子表,再刪除父表
2、如果要作為子表外鍵的父表列,那么這個列必須要設置為唯一約束或者主鍵約束
3、如果現在主表中的某一行數據有對應的子表數據,那么需要先刪除子表中的數據才可以刪除父表中的數據 ,刪除父表之后,子表的數據也會刪除
4、設置為外鍵的字段,在主表之中必須是主鍵或者是唯一約束。
級聯刪除:on delete cascad :在刪除父表的數據的時候,會自動刪除子表關聯的數據
級聯更新: on delete set null 現在刪除父表數據的時候,將對應的子表的數據的外鍵列設置為null
七、修改約束 100%禁止修改
約束必須在表創建的時候就應該要創建完整,不能進行約束修改。
六、數據庫的設計
1、第一范式:
數據表中的每一列的內容不可再分;
注意點:
1、對於日期描述堅決不能拆分為:年、月、日
2、對於姓名的字段不可分為fistname、lastname
1、第二范式(多對多關系)
數據表中不存在非關鍵字段對任意一候選關鍵字段的部分函數依賴。
2、第三范式:(一對多關系) 首要考慮
數據表之中不存在非關鍵字段對任意一候選關鍵字段傳遞函數依賴。
七、其他的部分
一、數據庫的備份
1、數據的導出與導入,以用戶為單位
數據表中的數據的導出與導入:
需要先准備一個數據備份的目錄,如:在cmd中輸入 md 文件夾名稱創建文件夾
進入該目錄下,以命令行的形式操作:輸入exp命令,導出數據
進入該目錄下,以命令行的形式操作:輸入imp命令,導入數據
2、數據庫的冷備份,歸檔備份,指數據庫需要關閉服務,所有的事務都需要提交了。
備份文件:
1、控制文件:控制着整個oracle 的實例信息,可以使用‘v$controlfile’數據字典找到
2、重做日志文件:通過‘v$logfile’數據字典找到
3、數據文件:通過‘V$datefile’數據字典找到
4、核心配置文件(Pfile):使用‘SHOWPARAMETE pflie’找到
數據庫備份操作需要使用管理員進行操作:
1、數據庫管理員登陸:
CONN sys/change_on_install AS sysdba;
2、找到以上幾份文件的路徑:
select * from v$controlfile;
select * from v$logfile;
select * from V$datefile;
SHOW PARAMETER Pfile;
記錄下以上文件的路徑
3、關閉oracle 服務:
shutdown immediate;
4、拷貝出所有的備份文件
5、重啟服務
startup;
2、數據庫的其他的對象
一、同義詞(oracle的專屬功能)
同義詞的定義:如果在sys用戶下,去使用select * from emp;的語法查詢emp表,他會報該表或者視圖不存在的提示,原因是因為emp表是屬於scott用戶的,所以在其他用戶下如果需要訪問該表,就應該要添加scott.emp ,這樣的過程就叫做同義詞。
語法:create 【public】 SYNONYM 同義詞名稱 for 模式.表名稱
例:將scott.emp 映射為semp;
create SYNONYM semp for scott.emp;
注意:在創建同義詞的時候,如果沒有將其創建為公共同義詞的話,那么該同義詞就只能在創建的用戶下使用,不能在其他的用戶下使用。
創建公共的同義詞:
create PUBLIC SYNONYM semp for scott.emp;
使用賬號密碼登陸:
CONN SYS/change_on_install as sysdba;
刪除同義詞:
drop SYNONYM SEMP;
二、索引來源與作用
在數據庫中進行數據查詢的時候,我們可以打開追蹤器對數據庫的分析過程進行分析
打開追蹤器:set autotrace on; 需要在sys用戶下才可以查看
根據查看后的結果,分析到:在數據的執行過程中,比如簡單的select * from emp where sal>1500; 該語句的執行過程是對該表進行全盤掃描,如果在數據量足夠大的情況下,如果后半部分的數據已經不滿足條件了,但是該語句還是會對后續的數據進行查詢,這樣就會造成資源的浪費也會拉低性能;
因此我們采取先排序的方式對數據進行排序,這樣就可以避免后續的資源被浪費了,但是不能使用order by ,因為order by 的執行順序在最后,是對已經篩選好的數據進行排序;
二叉數的排序方式:
選擇一個數據作為根節點,比節點數大或者等於的數據放在右子數上,比節點小的數據放在左子數上。(右大左小)

使用索引的方式實現對數據的分類搜索,以提高性能節約資源。
三、創建索引
1、創建引索就必須要設置一個指定的字段:
例:為scott.emp 表的sal字段創建索引
create INDEX emp_sal_ind ON scott.emp(sal);
2、再對select * from scott.emp where sal>1500;進行查詢,此時查詢的方式是采取索引的方式進行查詢且根據的是rowid :TABLE ACCESS BY INDEX ROWID /INDEX RANGE SCAN
3、缺陷
索引的局限性:索引可以提升查詢的速度與性能,但是也有很多的局限性,比如:如果數據一直在更改過程中的話,那么索引就不好用了。
樹的維護是需要花費大量的時間的,如果現在不想重復的對樹進行維護,那么就需要保證數據的不可更改與唯一性,所以在默認情況下會在主鍵約束上自動加上一個索引
在現實過程中:我們既希望保證用戶的回應速度快,沒有延遲,又能夠承受住用戶的大量更新,那么我們可以這樣處理:
犧牲實時性:
分成兩個數據庫,一個數據庫保存用戶需要查詢的數據,一個數據庫用來保存用戶的更新的操作,在凌晨2-3點時,再將更新數據庫的數據將數據更新到查詢庫中。
四、用戶管理(用戶的維護與權限的划分)
用戶登陸:
CONN sys/change_on_install AS SYSDBA;
創建新的用戶dog /wangwang (用戶名/密碼): 注意密碼要以英文字母開頭
CREATE USER dog IDENTIFIED BY wangwang;
賦予權限:
GRANT 權限1 ,權限2..... to 用戶名
例:GRANT create session to dog ;
問題來了,但是一個全新的用戶是沒有任何權限的,需要這個用戶可以正常使用的話,就必須要每種權限都使用單獨賦予的語句,這樣太過麻煩,所以引入角色的概念,不同的角色有不同的很多的權限,就不需要再單獨賦予權限了,只需要賦予該用戶角色就可以了。
CONNECT:連接角色,CONNECT角色中包含RESOURCE權限
RESOURCE:訪問操作(訪問表及表空間)
角色賦予:
GRANT CONNECT , RESOURCE TO dog;
用戶得到新的權限后必須要重新登錄后,才可以獲取新的權限。登錄操作並不是只是簡單的驗證用戶名與密碼,而是需要進行權限的獲取與驗證。
修改用戶的密碼:
ALTER USER 用戶名 IDENTIFIED BY 密碼
讓用戶的密碼過期:
ALTER USER 用戶名 PASSWORD EXPIRE;---使用這條指令后,會讓用戶自己輸入新的密碼,從而進行密碼的更改。
鎖定用戶:
ALTER USER 用戶名 ACCOUNT LOCK;
解鎖用戶:
ALTER USER 用戶名 ACCOUNT UNLOCK;
除了系統權限之外,還需要使用對象的權限:可以針對一個對象下的數據表進行訪問:四種權限:INSERT/UPDATE/DELETE/SELECT
例:將scott.emp 的表的select 、insert權限賦予dog用戶:
GRANT SELECT, INSERT on scott.emp TO dog;
權限的回收
REVOKE SELECT, INSERT on scott.emp FROM dog;
刪除用戶操作:
DROP USER 用戶名 CASCADE
3、序列
一、自動增長列 序列
語法:
create sequence 序列名稱
【MAXVALUE 最大值 | NOMAXVALUE】默認最大值:1.0000E+28
【MINVALUE 最小值 | NOMINVALUE】默認最小值為1
【INCREMENTBY 步長 】默認步長為1
【START WITH 開始值】
【CYCLE|NOCYCLE】默認為N,循環
【CACHE 緩存個數|NOCACHE】默認為20個?這個好像是更改的,后續說
序列屬於數據庫對象的創建過程,屬於DDL的分類范疇,對於序列的而言,創建之后一定會在數據字典中保存
例:CREATE SEQUENCE myseq;
nextval :取得序列的下一個內容,每一次調用序列的值都會增長
currval:表示取得序列的當前內容,每次調用序列都不會增長,就相當於顯示當前的序列
如果第一次沒有使用nextval取得值,那么使用currval是不能顯示當前的數據,就像相當於沒有值
二、定義特殊的序列
創建一個表:
create table mytab(
id number,
name varchar2(20),
constraint pk_id primary key (id)
);
創建表之后可以根據序列讓id進行自動增長:
insert into mytab (id , name ) values (myseq.nextval,'hello');
緩存的作用:緩存的作用是為了提高性能的,先准備數據,之后就可以直接使用了,但是在使用的過程中,會出現丟號的情況,該問題無法解決。
select myseq.nextval from dual; ---從虛擬表中查找序列
select sequence_name, cache_size ,last_number from user_sequences;---在數據字典中查找相關的信息
drop sequence myseq ;----刪除該序列
create sequence myseq;---創建該序列
INCREMENTBY 2;---設置步長為2
START WITH 1000;---改變序列的開始值
CYCLE;---設置循環
注意:last_number的值是等於步長*緩存數量的
cache 的值必須小於cycle的值:緩存的個數必須小於循環的值
4、視圖的定義與使用
一、視圖的創建
概念:利用視圖可以實現復雜的sql的語句的封裝操作
視圖屬於DDL的定義范疇,語法如下:
create【or replace】 view 視圖名稱 as 子查詢
例:
---給scott用戶創建視圖的權限:
CONN sys/change_on_install AS SYSDBA;
GRANT CREATE VIEW TO scott;
CONN SCOTT/TIGER;
---創建視圖:將emp表中的部門為10的人員信息封裝成視圖
create view myview as select * from emp where deptno=10;
視圖可以像普通的數據表那樣進行直接的查詢:
select * from myview;---查詢的結果與之前的子查詢的結果是一樣的
視圖很少用drop語句進行刪除,因為在刪除與創建的過程中,會存在時間間隔,會導致存在問題,所以如果遇到視圖存在的問題,我們采取替換掉的方式將其進行更新:
create or replace view myview as select * from emp where deptno=10;---如果視圖不存在,則創建,如果存在,則替換更新
二、視圖的更新操作
視圖中只是包含查詢語句的臨時數據,並不是真實存在,但是默認情況下,視圖是可以進行直接修改的
create or replace view myview as select * from emp where deptno=10;
更新視圖的部門編號:
update myview set deptno=30 where empno=7369;
注意:
1、保護創建條件不被更改:在視圖中更新的數據,同時也是會在原始的emp的數據同時更新:這樣的操作是不合理的,所以為了防止更改視圖導致數據的更新操作的情況,在創建視圖的時候使用 with check option 的子句,防止視圖的創建條件不被更改。
create or replace view myview as select * from emp where deptno=10 with check option ;
2、視圖不可以修改除創建條件外的其他字段,在創建視圖的時候,是屬於數據的映射,那么本質上應該創建一個只讀的視圖,以保護數據不被修改
create or replace view myview as select * from emp where deptno=10 with read only