1. 程式人生 > >【數據庫系統概述】

【數據庫系統概述】

整體 模糊 std 運行 years ces nth 時間戳 記事本


常用的數據庫有MySql、oracle等。不同數據庫都支持sql標準,並且不同數據庫在sql標準的基礎上進行了一些擴充。
對於數據庫的學習包括:sql>過程、觸發器等內容,其中重要程度如下:
sql>過程、觸發器等
oracle數據庫:
1、oracle的開發部分,包含兩個部分:sql+plsql編程
2、oracle管理部分,數據庫配置和運行維護
【oracle簡介】
oracle默認有sys和system兩個用戶,其中
sys: 超級管理員,擁有操作數據庫的所有權限
system:普通管理員
註意:安裝oracle後會出現多個服務,可以設置為手動啟動
重要的兩個服務為:
1、數據庫監聽服務,如果要通過遠程客戶端(如sql develop等)連接數據庫,或者直接用程序連接數據庫,那麽此服務必須打開
2、數據庫實力服務:每個數據庫都會有這種服務名稱如:OracleServiceSID
【sqlplus簡介】
sqlplus 首先將sql語句放到緩沖區,然後將緩沖區的sql語句提交到數據庫執行;
oracle12c 之中默認數據找不到,需要對數據進行恢復,找scott.sql文件目錄下為數據
通過修改SCOTT.sql修改恢復數據
數據配置執行順序為:
1、打開sqlplus /nolog
2、運行C##scott.sql
【sqlplus 常用命令】
1、格式化命令:
數據顯示出現換行問題,出現數據分頁:
1、首先要解決屏幕寬度:set linesize 300
set pagesize 30
2、方便編寫長數據庫腳本,可以調用記事本:ed,可以在技術本中編輯查詢命令,隨後可以使用@ 標記執行數據庫腳本
sqlplus執行sql腳本的方法:使用@+腳本
3、連接操作
用戶之間可以互相切換
CONN 用戶名/密碼【as sysdba】
可以通過show user查詢當前用戶
在sys中查詢Scott中的表,需要添加用戶名在表明前
select * from tab;查詢所有的表
查看數據表的結構DESC:desc emp;
執行host命令:host+命令
host dir;

關於原始用戶的問題:
恢復原始數據:
1、登陸sys用戶: conn sys/Oracle123456 as sysdba
2、查看現在的容器名稱:show con_name;
返回值為:CDB$ROOT 為一個CDB容器
3、改變容器為PDB: alter session set container=pdborcl;
4、打開pdb數據庫:
alter database pdborcl OPEN;
5、查看用戶
打開sh和scott用戶
6、切換回cdb
alter session set container=cdb$root


語法:
SELECT[DISTINCT] *|列名 [as] 列別名,列名 [as] 列別名.... FROM 表名 表別名
使用as設置別名,別名最好不要使用中文
簡單查詢中兩個字句:
1、select字句
distinct 表示去除重復列,僅限於所有列的內容都相同
2、from子句
關於字句的執行順序:
1、from字句,確定數據來源
2、select字句,確定要顯示的列
select中的四則運算:
當參與運算的數值中含有null值時,結果返回為null
查詢月薪、日薪等
select sal+comm msal from emp;
添加常量列:
select ‘y‘ as cl from emp;
利用“||”進行字符串連接
select ‘編號是:‘||empno||‘姓名是:‘||ename from emp; 字符串是用單引號引起來
【限定查詢】

1、語法:
SELECT[DISTINCT] *|列名 [as] 列別名,列名 [as] 列別名.... FROM 表名 表別名 where 條件語句
連接多個條件的邏輯運算符:and or not

限定查詢有三個字句,執行步驟為:
1、執行from字句,來控制數據的來源
2、執行where字句,使用限定對數據行過濾
3、執行select字句,來確定數據列

常用限定運算符:
1、關系運算符,確定大小相等關系的比較
select * from emp where sal《=2000
select * from emp where ename=‘smith‘
在使用關系運算符判斷字符串時需要註意大小寫,並且字符串用單引號;字符串可以直接用“=”比較
不等於符號“<>”和"!="兩種操作形式
select * from emp where ename!=‘JAMES‘;
select * from emp where ename<>‘JAMES‘;
工資範圍1500到3000
select * from emp where sal>1500 and sal<3000;
銷售人員基本工資高於1200
select * from emp where sal>1200 and job=‘saleman‘;

範圍查詢
between and 操作符 包含最大值和最小值
查詢出1981年雇員的全部信息;則範圍是1981-1-1--1987-12-31
select * from emp where hiredate between ‘01-1月-81‘ and ‘31-12月-81‘;

判斷內容是否為null:IS NULL/IS NOT NULL(只能這樣判斷)
註意:null不能用等號判斷
select * from emp where empno=7369 and comm is null;

列表範圍查找:IN/NOT IN
所謂列表範圍是指給定了用戶的幾個值,必須在這些值範圍內
select * from emp where empno IN(7369,7788);
select * from emp where empno not IN(7369,7788);
註意:
關於null的問題,如果在in操作符中包含null;不會影響最終的查詢結果,如果在not in中包含null,直接的後果是沒有任何數據顯示
select * from emp where empno not IN(7369,null);數據庫系統的限制,not in 中有null不返回任何值

【模糊查詢】
like/not like
like字句中可以使用連個通配符:
百分號%:可以匹配任意類型和長度的字符,如果是中文則使用兩個百分號%%;(出現一次0次或者多次)
下劃線_:匹配單個任意字符,它常用來限制表達式的長度(出現一次)

以J開頭的:
select * from emp where ename LIKE ‘J%‘;
查詢字母中任意位置包含J,前後都有的問題用百分號
select * from emp where ename LIKE ‘%J%‘;
名字長度大於六個字符的:
select * from emp where ename like‘_____%‘;
LIKE可以用於數字或者時間類型上面,關鍵字為空表示查詢全部

【數據排序顯示】
order by 默認升序
傳統數據查詢的時候只會設置的逐漸排列,如果希望對指定的列進行排序,就需要使用order by 排序
語法:
SELECT[DISTINCT] *|列名 [as] 列別名,列名 [as] 列別名.... FROM 表名 表別名 where 條件語句 order by ASC|DESC
ASC:升序
DESC:降序
在所有sql字句中order by是放在查詢語句的最後一行,是最後一個執行的字句,
select * from emp where sal>1000 order by sal asc;
範例:按照工資高到底排序,工資相同,按照雇傭日期早到晚
select * from emp order by sal desc,hiredate;

【單行函數】
語法:
function_name[列] 表達式[參數1,參數2]
單行函數主要分為以下幾種:
1、字符函數
以字符數據為主(字符串)
UPPER()和LOWER()函數轉換大小寫;ABCD
SELECT UPPER(‘abcd‘) from dual;
select LOWER(ENAME) FROM EMP;
SUBSTR()函數
select substr(‘abc‘,2) from dual;--返回bc
select substr(‘abc‘,-1) from dual;--返回c;負數是從後面數為oracle特有的,下標從1開始
ASCII碼:
select ascii(‘A‘) from emp; 65
select chr(100) from dual; d
trim函數:
select ltrim(‘ adf‘) from dual;去掉左邊空格
select rtrim(‘ adf ‘) from dual;去掉右邊空格
select trim(‘ adf ‘) from dual;去掉空格
填充:
LPAD
select lpad(‘ad‘,4,‘*‘) from dual; **ad
查找函數:
instr
select instr(‘floor‘,‘oo‘) from dual; 3
select instr(‘floor‘,‘QQ‘) from dual; 0
2、數值函數
round 四舍五入
select round(123.456) from dual; 123 不保留小數
select round(123.456,2) from dual;123.46 保留兩位小數
select round(123.456,-2) from dual; 100 整數部分取整
trunc 截取位數
select trunc(123.456,2) from dual; 123.45
mod 取模
select mod(10,3) from dual; 1

3、日期函數
日期的計算操作和日期函數的使用
1、取得當前日期:利用sysdate偽列取得當前時間
select sysdate from dual;20-8月 -16
默認情況下只包含了年月日三個內容,可以通過修改默認的語言方式來修改日期格式
日期的算數運算:
若幹天前的日期:日期-數字=日期
select sysdate-3 from dual; 17-8月 -16

若幹天後的日期:日期+數字=日期
select sysdate+3 from dual;23-8月 -16

兩個日期的天數間隔:日期-日期
select trunc(sysdate-hiredate) from emp; 雇傭天數

日期的計算函數:
ADD_MONTHS()函數
select add_months(sysdate, 3) from dual;20-11月-16 三個月之後的日期
select add_months(sysdate, -3) from dual;20-5月 -16 三個月之前的日期
NEXT_DAY()函數
select NEXT_DAY(sysdate, ‘星期日‘) from dual; 查詢下一個星期日
last_day()函數
select last_day(sysdate) from dual; 本月的最後一天31-8月 -16
查詢當月倒數第三天雇傭的
select ename from emp where hiredate=last_day(sysdate)-2;
Month_between()月數
select trunc(MONTHS_BETWEEN(sysdate, hiredate)/12) 雇傭年數 from emp;
範例:計算出某一個雇員目前為止雇傭的年數,月數,天數**

1、需要查詢的表:emp
select ename,trunc(months_between(sysdate,hiredate)/12) years,
trunc(mod(months_between(sysdate,hiredate),12)) months,sysdate-(last_day(add_months(sysdate,-1))+1) days from emp;
select ename,month_between(sysdate,hiredate)/12 years

4、轉換函數
主要使用的數據類型:字符、數字和日期(時間戳)
TO_CHAR()
將date類型變成字符串:
select to_char(sysdate,‘yyyy-MM-dd hh24:mi:ss‘) from dual; 2016-08-20 20:26:25
select to_char(sysdate,‘FMyyyy-MM-dd hh24:mi:ss‘) from dual; 2016-8-20 20:30:14 去除前導0
查詢出每年二月份雇傭的雇員信息
select * from emp where to_char(hiredate,‘MM‘)=2;
拆分日期;
select ename ,empno,to_char(hiredate,‘yyyy‘) 年,to_char(hiredate,‘MM‘) 月,to_char(hiredate,‘dd‘) 日 from emp
where to_char(hiredate,‘MM‘)=2;ALLEN 7499 1981 02 20
TO_CHAR()格式化數字:
TO_DATE()函數;字符串-->日期比較少
TO_TIMESTAMP()
TO_NUMBER()基本不用
select to_number(‘09‘) from dual; oracle中支持自動的類型轉換,select 09 from dual; 結果相同

5、通用函數:oracle提供的特色函數
NVL()函數用於處理null值
範例:查詢年薪;有null參與的運算結果為null
select nvl(sysdate-null,sysdate) from dual 20-8月 -16 為null的時候為sysdate
NVL2()函數
select nvl2(comm, sal+comm,sal) from emp
NULLIF,相同的結果返回空

DECODE()函數
oracle最有特色的函數之一,類似於if else,但是判斷的內容都是一個具體的值
select DECODE(2,1, ‘Ground‘, 2,‘Air‘,‘默認值‘) from dual; 如果值為1,返回Ground,如果值為2,返回air,沒有匹配的返回“默認值”
註意:使用decode()函數判斷,所有可能出現的數值都要判斷,沒有判斷的內容為null,

oracle9i後引入case表達式,根據給定的列或者字段依次判斷
select ename,sal,
case job
when ‘clerk‘ then sal*1.1
when ‘salesman‘ then sal*1.2
else
sal*1.5
end 新工資
from emp;

【多表查詢】復雜查詢
多表查詢先使用笛卡兒積的方式查出所有記錄,再通過條件進行篩選
語法:
SELECT [DISTINCT] *|列明 as 列明 from 表名,表明2... where 條件語句
笛卡兒積問題:
select * from emp; 14條記錄
select * from dept; 4條記錄
select * from dept ,emp;56條記錄4*16
隱藏掉笛卡兒積列:使用關聯字段
select * from dept t ,emp e where t.deptno=e.deptno; 顯示14行
註:數據量很大的時候一般不用多表查詢,因為笛卡兒積肯定是存在的,關聯字段只是隱藏掉笛卡兒積的記錄,並沒有消除笛卡兒積
範例:
查詢每個雇員的編號,姓名,職位,基本工資,部門名稱,部門職位信息
1、確定所需要的表:
emp表:雇員編號,姓名,職位,基本工資
dept表:部門名稱,部門職位信息
2、確定關聯字段
emp.deptno=dept.deptno
select e.empno,e.ename,e.job,e.sal,d.dname,d.loc
from emp e,dept d
where e.deptno=d.deptno;
按照sql語句的執行步驟編寫:FROM WHERE SELECT
範例:查出每個雇員的編號,姓名,雇傭日期,基本工資,工資等級
1、確定所需要的表:
emp:雇員的編號,姓名,雇傭日期,基本工資
salgrade:工資等級
2、確定關聯字段
sal
select e.ename,e.hiredate,e.sal,s.grade
from emp e,salgrade s
where sal between losal and hisal;
範例:查詢出每個雇員的姓名、職位、基本工資、部門名稱、工資等級
1、確定所需要的表:
2、確定關聯字段
步驟一:查出雇員信息
步驟二:查出部門表(消除笛卡兒積)
步驟三:查出工資等級表
步驟四:等級換成中文
select e.ename,e.job,e.sal,d.dname,s.grade,
case s.grade
when 1 then ‘第五等‘
when 2 then ‘第四等‘
when 3 then ‘第三等‘
when 4 then ‘第二等‘
when 5 then ‘第一等‘
end sg
from emp e,dept d,salgrade s
where e.deptno=d.deptno and sal between losal and hisal;

【多表查詢】表的連接操作
目標:清楚表的連接區別:內鏈接和外連接
內連接:通過關聯字段等值判斷進行連接,消除關聯字段不相等的連接,來隱藏笛卡兒積現象
範例:內外鏈接的區別:
1、添加一個沒有部門信息的雇員
2、執行以下查詢語句
select * from emp,dept where emp.deptno=dept.deptno;
沒有部門信息的員工沒有顯示,如果希望emp或者dept表中的數據顯示完整,那麽可以利用外連接
範例:使用做外連接希望emp信息全部顯示:

外連接:如果想要某一個表的字段全部顯示,則可以使用外連接通過"(+)"進行控制,只能在oracle中使用(+)
此符號只能實現左邊外連接或者右外連接
左外連接:select * from emp e left outer join dept d on e.deptno=d.deptno;
右外連接:select * from emp e right outer join dept d on e.deptno=d.deptno;
全外連接:select * from emp e full outer join dept d on e.deptno=d.deptno;
註意:只能在oracle中使用(+)進行外連接

自身關聯:
emp中mgr字段表示雇員的領導信息:
如果要顯示領導信息,需要利用雇員表和雇員表自己的連接操作完成
範例:查詢出雇員表中的雇員姓名、編號和上級領導的編號和姓名

對於沒有領導信息的雇員,對應領導信息全部使用null進行連接
King沒有mgr信息,沒有顯示;解決方法外連接

範例:查詢在1981年雇傭的全部雇員編號、姓名、雇傭日期(年月日顯示)、工作領導姓名,月工資,年工資(基本工資+傭金)工資等級,部門編號,名稱,位置,同時要求這些雇員的月工資在1500-3500之間,
最後按照年工資進行降序排列,工資相同,按照工作排序
1、確定所需要的數據表
2、確定已知的關聯字段
數據的集合運算
集合運算是一種二目運算符,一共包含四種運算符,並差交笛卡兒積:
語法如下:
查詢語句
[union|union all |intersect|minus]
查詢語句
select * from dept; 4條結果
select * from dept where deptno=10; 一條結果
兩個查詢結果返回的結果結構相同
union(並集)返回若幹個查詢結果的全部內容,但是重復元祖不顯示
select * from dept union
select * from dept where deptno=10; 4條結果
union all(並集)返回若幹個查詢結果的全部內容,重復元祖也會顯示
select * from dept union all
select * from dept where deptno=10; 5條結果
範例:查詢所有銷售和辦事員的信息
select * from emp where job in(‘clerk‘,‘salesman‘);
select * from emp where job=‘clerk‘ or job = ‘salesman‘;
註意:盡量使用union或者union all來代替or,集合操作時,各個查詢的結果結構一定要相同
select * from emp where job=‘clerk‘
union
select * from emp where job= ‘salesman‘;

minus(差集) 返回若幹個查詢結果中的不同部分
intersect(交集)返回若幹個查詢結果中的相同部分


分組統計查詢:
1、統計函數
掌握標準統計函數的使用:
COUNT(*|distinct 列)求出全部的記錄數
count中的參數可以使用*也可以使用字段和dinstinct
select count(*),count(empno) from emp; empno沒有null值,結果一樣
select count(*),count(mgr) from emp;15,14
範例:count(*)、count(字段)、count(dinstinct)有什麽區別
1、全部統計
2、不統計null值
3、不統計重復值
盡量不使用*,所有函數在沒有數據的時候都是返回null;但是count在沒有數據的時候返回0,所以在java中是不需要對結果進行判斷的


SUM()求和
AVG()平均值
MAX()最大值
MIN()最小值
median()中間值
STDDEV()標準差

範例統計處公司最早雇傭的和最晚雇傭的
雇傭日期使用的是date類型,但是在Oracle中的函數是可以進行數據類型的互相轉換的,最早雇傭的hiredate值一定是最小的
select min(hiredate) zuizao,max(hiredate) zuiwan from emp;

單字段分組查詢
掌握group by的使用
需求一:公司中要求每個部門一組進行拔河比賽
需要部門列的內容需要重復
select * from emp
job和deptno有重復內容,最好對有重復內容的列進行分組
需求二:在一個班級中要求男女各一組進行辯論比賽
語法:
select 分組字段|統計函數 from 表明 group by 分組字段
分組使用group by子句時,但是此時SELECT子句允許出現的就是分組字段和統計函數***
範例:統計處每個部門的人數
select deptno ,count(empno)
from emp
group by deptno;
範例:統計出每種職位的最低和最高工資
select job,min(sal),max(sal)
from emp
group by job;
掌握分組查詢的使用限制(最為麻煩的地方為此處的限制)
註意事項一:
如果一個查詢之中不存在group by 子句,select子句中只允許出現統計函數,其他任何字段都不允許出現
select deptno ,count(*) from emp; 提示”不是單組分組函數“錯誤
註意事項二:
在統計查詢之中(存在group by子句) select子句中只允許出現分組字段(group by後面的字段)和統計函數其他任何字段都不允許出現
註意事項三:
所有的統計函數允許嵌套使用,但是一旦使用了嵌套的統計函數之後,select字句中不允許出現任何字段,包括分組字段
範例:
求出每個部門平均工資最高的工資
按照部門分組,而後統計處每個部門的平均數值,那麽針對這些統計結果求出一個最大值
範例:
查詢每個部門的名稱、部門人數、平均工資,平均服務年限
1、確定所需要的數據表
2、確定已知的字段關聯


字句執行順序
from where group by select order by
範例:查詢出公司各個工資等級雇員的數量和平均工資
1、確定所需要的表
2、確定關聯字段
範例:統計處領取傭金和不領取傭金雇員的平均工資、平均服務年限、雇員人數
1、
2、
多字段分組:
既然可以在group by子句中出現多個分組字段,那麽在select子句中也可以出現多個字段
範例:要求查詢出每個部門的詳細信息
包含字段:部門編號、名稱、位置、平均工資、總工資、最高工資、最低工資、部門人數。(使用多字段分組)
1、確定已知的數據表
2、確定關聯字段
having子句
掌握having字句的使用
當需要對group by分組之後的數據再進行過濾,則只能通過having子句完成
註意:having子句必須和group by子句一起使用
查詢出所有平均工資大於2000的職位信息、平均工資和雇員人數
select job,round(avg(sal)),count(empno)
from emp
group by job having avg(sal)>2000
語句的執行順序 from、where、group by, having, order by
範例:
列出至少有一個員工的所有部門編號,名稱,並統計出這些部門的平均工資、最低工資、最高工資
1、確定所需要的數據表
2、確定已知的關聯字段:
子查詢
子查詢中的語法格式並沒有任何新的技術,類似於java的內部類,而且在開發之中,子查詢的使用絕對是比較多的
復雜查詢=限定查詢+多表查詢+統計查詢+子查詢,在筆試之中出現較多的部分。
範例:查詢公司之中工資最低的雇員的完整信息
select * from emp where sal=(select min(sal) from emp);
根據返回的數據類型一共分為四種:
單行單列
單行多列
多行多列
多行單列
多行多列
子查詢出現的地方:
1、where
單行單列
範例:查詢出基本工資比allen工資低的員工

範例:查詢出基本工資高於公司平均工資的雇員

範例:查找出於ALLEN工作相同,並且接你工資高於雇員編號7521的全部雇員信息
範例:查詢出與SCOTT從事同一工作並且工資相同的雇員(返回單行兩列)
select * from emp where (job,sal)=(select job,sal from emp where ename=‘SCOTT‘);
select * from emp where (job,sal)=(select job j,sal s from emp where ename=‘SCOTT‘); 列不對應
範例:查詢出與7566工作相同並且領導相同的雇員
範例:查詢出於ALLEN同一工作並且同一年雇傭的雇員信息
多行單列:
如果子查詢返回的是多行單列,主要使用三種操作符:in,any,all,not in
範例:查詢出與每個部門最低工資相同的全部雇員信息
範例:查詢出不與每個部門中最低工資相同的全部雇員信息
註意:如果在in中子查詢的結果又in,如果在not in中子查詢返回數據有null就表示不會有任何數據返回
any操作符
=any:功能和in相同,但是<>any不等價於not in;
>any比最大值要大
<any比最小值要小
範例:
all操作符
空數據判斷
exists用於判斷是否有數據返回
select * from emp where exists(select * from emp where empno=9999);子查詢沒有內容,不返回
select * from emp where exists(select * from emp); 有結果返回,數據會全部返回
2、having,一定表示操作會執行分組
在having中的子查詢一般會返回單行單列,是以一個數值的方式返回
範例:查詢部門編號、雇員人數、平均工資,並且要求部門平均工資高於公司的平均工資
範例:查詢每個部門平均工資最高的部門名稱以及平均工資(在統計函數嵌套使用時select字句中不允許出現任何字段,包括分組字段)
3、from 主要功能是確定數據的來源,來源都是數據表(行+列的集合),所以一般都是多行多列子查詢
範例:查詢出每個部門的編號、名稱、位置、部門人數、平均工資(可以使用多表查詢和子查詢兩種方法)
使用子查詢來代替多表查詢來避免笛卡兒積,所以優先使用子查詢
範例:查詢出所有在部門‘sales’工作的員工編號、姓名、基本工資、獎金、職位、雇傭日期、部門的最高和最低工資
1、確定所需要的數據表

對於統計函數的使用限制:
單獨使用:不允許出現任何字段
和group by一起使用:允許出現分組字段
範例:查詢出所有的新近高於公司平均薪金的員工編號、姓名、基本工資、職位、雇傭日期、所在部門名稱、位置、上級領導姓名、公司的等級、部門人數、平均工資、平均服務年限。
1、確定所需要的數據表
2、確定已知的關聯字段
範例:列出公司各個部門的經理姓名、薪金、部門名稱、部門人數、部門的平均工資
1、確定數據表
2、確定關聯字段
4、select用的比較少
範例:查詢出部門編號,部門名稱,部門人數,部門平均工資
with子句
可以使用with創建臨時表查詢
範例:查詢每個部門的編號,名稱、位置、部門平均工資,人數(使用with)
範例:查詢每個部門工資最高的雇員編號、姓名、職位、雇傭日期、工資、部門編號、部門名稱,最終的顯示結果按照部門編號排序

分析函數:
理解分析函數的主要語法:
理解分窗的使用
刪除語法:
delect from 表明 where
更新語法:
update 表明 set a=b where
【事務處理】
指同一個session中的所有sql語句整體執行
服務器通過session來區分不同的用戶,每一個session對應一個用戶
原子性、一致性、隔離性和持久性
session---緩存
更新操作要commit之後才會生效
ROLLBACK回滾,savepoint+保存點名稱
鎖的基本概念
鎖指的是不同的session同時操作了同一資源發生的問題
兩個session執行同樣的update操作語句:
兩種鎖:
行級鎖:
特點:當一個事務執行了相應的數據操作後如果此事務沒有提交,那麽會一直以獨占的方式鎖定這些操作的數據,其他事務要一直到此事務釋放後才能進行操作
表級鎖:

【數據庫系統概述】