MySQL,Oracle系統學習,以及SQL語言-----數據庫篇學習筆記

MySQL和Oracle系統學習

一. 開篇立意(必看,有說明)

  1. 自我系統性學習數據庫知識,包含基本SQL語句學習,MySQL.Oracle的學習,以及區別,後續會增加優化篇,水平有限,錯誤之處請批評.
  2. 這是我學完之後總結內容,很全,但是邏輯順序不適用新手, 可以參考順序學習:
    - Oracle篇
    - 基礎概念
    - 表數據的操作
    - 二維表的創建,維護之流
    - 用戶的操作
    -

二. Oracle 篇

數據庫存在之意義

我之理解,數據庫的目的就是長期有效的存儲數據,並且對數據在硬盤上進行有序排列.

基礎概念(必須看,後面不會說明!!!)

元組=記錄=行數據
屬性=字段=列數據
域:屬性的取值範圍
主鍵:辨別每行的一個或一組字段,用以區別其他元組.
別名(alias): 對字段和表起一個名字,用來簡化操作. 
語法: 字段名  [as ]別名 
		 表名   [as] 別名 

其中'[]' 部分可以省略.

Oracle管理系統的介紹

  1. 下載略之…: [我安裝的之 Oracle 11g ]
  2. 驗證: 打開sql命令界面:輸入conn system.然後提示輸入密碼,即可.顯示已連接,安裝成功,

一些說明:

  • 因爲Oracle基於C/S架構,所以基本交互流程是:Oracle client 通過ip,port,protocol,庫名 尋找Oracle服務器,在連接數據庫.
  • 第三方管理軟件: 我首選Navicate premium 15, 執行Google,後期可能看情況出教程.
  • 關於連接: 選擇TNS 模式, 這樣自己學習時候會方便一些,具體原因略之.
  • OracleXE 自帶賬戶: system sys 不帶普通用戶.Oracle11g 默認帶一個普通用戶scott 默認密碼tiger

賬戶操作

  1. 創建賬戶
--由於Oracle特性,先用system賬戶登錄系統,使用dba(數據庫管理員)身份,在通過system創建普通用戶(mysql非方便許多)
create user 用戶名 idenified by 密碼
eg. 
create user scott idenified by xxxxxx;
--給用戶賦予權限
--賦予數據庫登錄權限
grant connect to scott;

--賦予用戶資源操作權限
grant resource to scott;

--賦予用戶dba權限
grant dba to scott;

--更改密碼
alter user scott idenified by newPassword

--撤銷權限
revoke connect, resource from 用戶名;
  1. 刪除用戶 drop user 用戶名

三. SQL語言

  • SQL簡介:
    - 非面向過程語言:強調做什麼,而非如何做.
    - 作用:
    - 數據庫數據的增刪改查
    - 數據庫對象的創建,修改,刪除
    - 用戶權限/role之授予/撤銷
    - 事務控制
  • 組成:
--這是overview 概覽,後續有詳細的.
數據定義語言(DDL):
CREATE DATABASE - 創建新數據庫 
ALTER DATABASE - 修改數據庫 
CREATE TABLE - 創建新表 
ALTER TABLE - 變更(改變)數據庫表 
DROP TABLE - 刪除表 
CREATE INDEX - 創建索引(搜索鍵) 
DROP INDEX - 刪除索引

數據操作語言(DML):I
SELECT - 從數據庫表中獲取數據 
UPDATE - 更新數據庫表中的數據 
DELETE - 從數據庫表中刪除數據 
INSERT INTO - 向數據庫表中插入數據 

數據查詢語言(DQL):SELECT 語句。
數據控制語言(DCL): GRANT、REVOKE、COMMIT、ROLLBACK 等語句。

二維表的創建

約束

約束:  限制字段屬性的一些條件,譬如字段:年齡: 邏輯上講必須 0<age<120(人類理想壽命).這就是約束.

屬性約束有:				約束命名規則
      --主鍵約束			PK_表名_列名
      --非空約束			NN-表名_列名
      --檢查約束			CK_表名_列名
      --唯一約束			UK_表名_列名
      --外鍵約束			FK_表名_列名
     

約束的添加方法:
1. 聲明字段之後
2. 聲明表的末尾
3. 聲明表後修改/增加約束.

插嘴一句: Oracle中註釋是--xxxx, 兩個短槓後面加文字.
example
CREATE TABLE student (
sno number(10) primary key,
sname VARCHAR2(100) NOT NULL,
sage NUMBER(3) CHECK(sage>0 AND sage<120),
ssex CHAR(4) CHECK(ssex='male'OR ssex='female'),
sWeChat VARCHAR2(30) unique

--第二種方式
--添加主鍵
--constraints pk_表名_字段名 primary key(字段名)
--添加非空約束(其實就是檢查約束)
--constraints ck_student_sname check(sname is not null)
--添加檢查約束
--constraints ck_student_sage check(sage<120 and sage>0)
--添加唯一約束
--constraints un_student_sqq unique(sWeChat)
);

--備註: 最後一句一定不要有逗號',' , Oracle語法要求嚴格,不許出錯.


--第三種方法: 創建表之後
alter table 表名 add  constraints  約束名 pk_表名_字段名 primary key(字段名);
alter table 表名 add  constraints 約束名 ck_表名_字段名 check(字段名 is not null);
alter table 表名 add  constraints 約束名 un_表名_字段名 unique(字段名);

外鍵約束

--這裏外鍵約束單獨出來講解
--概念: 子表,父表
--現有一學生表, 裏面有一字段`cid` 班級號, 另有一表`class`,班級表,包含所有班級信息.裏面有字段`cid` (可以不同名,但值必須同).此時`student` 裏面有字段依賴於`class` 表,就說=tudent是子表,class是父表.

--1. 聲明字段後:
references clazz(字段名)
--2. 聲明表,最後
constraints fk_表名_字段名 foreign key(字段名) references clazz(字段名)
--3. 聲明表後,修改/增加約束
 alter table 表名 add constraints 約束名 fk_子表名_字段名 foreign key(字段名) references 父表名(字段名) on ;

######外鍵的缺點以及改善

--無法直接刪除父表數據,除非級聯刪除
--級聯刪除:
--在添加外鍵約束時,使用關鍵字 on delete cascade, 當刪除父表數據時,自動刪除子表相關所有數據。
alter table 表名 add constraints 約束名 fk_子表名_字段名 foreign key(字段名) references 父表名(字段名) on delete cascade ;

--使用關鍵字 on delete set null, 刪除父表數據時,將子表中的依賴字段的值設置爲null。注意:子表依賴字段不能添加非空約束。

刪除約束

alter table 表名 drop  constraints 約束名;
alter table 表名 add constraints 約束名 fk_子表名_字段名 foreign key(字段名) references 父表名(字段名);
--備註: 如果沒有設置約束名,系統會自動分配,使用語句:
SELECT * FROM USER_CONS_COLUMNS;
--查詢對應表對應字段分配的約束名.

序列

  • 意義: 方式主鍵衝突.
  • 序列是Oracle專有對象,產生一個自動遞增的數列.
--創建序列
create sequence 序列名
	
	--特點1:默認開始是沒有值的,也就是指針指在了沒有值的位置。
	--特點2:序列名.nextval每次執行都會自增一次,默認步長爲1
	--特點3:序列名.currval查看當前序列的值。開始是沒有的。
	--作用:作爲主鍵使用,動態的獲取之間的值,這樣新增數據的時候極大的避免了主鍵衝突.

--例子
create sequence xran
insert into STUDENT values(cc.nextval,'張三',30,'male','xran656510385');
insert into STUDENT values(cc.nextval,'張三',30,'male','xran656510385');
insert into STUDENT values(cc.nextval,'張三',30,'male','xran656510385');
select * from student
--會發現sno自增1

--如何設置指定的初始值和步長?
create sequence xran--創建序列
start with 3      --設置開始位置
increment by 2    --設置步長

--這次從3開始,每次增加2.

索引

  • 目的: 提升查詢效率
--索引在用戶查詢時自動起作用,通過使用快速路徑訪問方法快速定位數據,減少磁盤的I/O.
--創建: 兩種方式
--1. 聲明表時,定義primary key or  unique 約束時會自動創建索引,
--2. 手動創建
	create index 索引名 on 表名(字段名1,字段名2,..);
--刪除索引
     drop index 索引名;
     
--oracle會自動給表的主鍵創建索引。默認索引字段是主鍵.
--注意: 索引適用於數據量大,數據量小範圍效率低,因爲要按目錄去比對.簡而言之:索引類似一個目錄`content`, 按照需求快速的檢索數據.避免遍歷數據的巨大耗時.

視圖 VIEW

  • 我之理解:就是一個或多個表或從其他視圖中將不重要數據映射成一個表,供程序員查詢,修改,自動會同步到原表中,這樣避免重要數據的篡改.也就是說,只向外提供映射部分數據的表.
--創建視圖
          create view 視圖名 as select 對外提供的內容 from 真實表名 [with read only]
          --其中:[with read only] 表示對視圖設置只讀模式.
       
--刪除視圖
		  drop view 視圖名
		
--查詢視圖
		select * from 視圖名

 --特點1:保護真實表,隱藏重要字段的數據。保護數據。
 --特點2:在視圖中的操作會映射執行到真實表中
 --特點3:可以手動開啓只讀模式 使用關鍵字 with read only
 --注意:視圖的創建必須擁有dba權限--->詳見上述用戶管理部分.

分頁

  • 何爲分頁? 答曰: 將數據量很大的表分頁顯示,提供更加友好的界面.
--rownum關鍵字:oracle對外提供的自動給查詢結果編號的關鍵字,與每行的數據沒有關係

--注意:rownum關鍵字只能做< <=的判斷,不能進行> >=的判斷

--查詢學生表前五條信息,顯示咋在第一頁
select rownum, s.* from student s; where rownum<=5;
--查詢學生表第6-10條數據,顯示在第二頁
select stu.*  from (select rownum r ,s.* from student s where rownum <=10) stu where r>7;

--解釋: 因爲rownum只能操作<=,故,stepone: 將<=10的數據顯示出來, 因爲這也是一張表,所以可以賦予別名, 然後根據這樣表查詢 r>=6的部分.  (此時 r 是stu表中的一個字段).

--規律總結: 每頁顯示m條數據,查詢第n頁數據
select * from (select rownum r,e. * from 要分頁的表 e where rownum<=m*n) t where r>m*(n-1);
--感覺沒必要記憶,理解原理即可.

備份表

--這裏提供另外一種,有已知表創建新表,以可用作備份.
--1. 
create table 新表名 as select * from 表名 ;

二維表的維護

添加新字段

alter table 表名 add 字段名  類型;

修改原有字段

--1. 修改字段類型
alter table tableName modify fieldName type;
--eg.
alter table student modify sWhChat varchar2(11);

--2. 修改字段名
alter table tableName rename column fieldName to newFieldName ;

--3. delete field
alter table tableName drop column fieldNanme;

刪除表

drop table tableName

修改表名

rename 原表名 to 新表名

表數據的操作(關鍵時刻)

  1. 表的執行順序:
1). from
2). where
3). group by 
4). select
5). having
6). order by
--優先級遞減,order by 最後執行.顯示結果表.

null

  • 先講解null, 按我的邏輯來.
--1. 任何數據類型+null = null,
--2. 一些字段篩選條件:  
	is null
	is not null

select

SELECT [distinct] 列名稱 FROM 表名稱 ;
SELECT * FROM 表名稱
提示:星號(*)是選取所有列的快捷方式--通配符,詳見regular expression。

--關鍵字: distinct 取出結果表中重複的行;
					--作用範圍: 後面所有字段

order by

--ORDER BY 語句用於根據指定的列對結果集進行排序。
--ORDER BY 語句默認按照升序對記錄進行排序。
--如果您希望按照降序對記錄進行排序,可以使用 DESC 關鍵字
 
SELECT field1, field2 FROM table ORDER BY field1 DESC, field2 ASC
--在第一列中有相同的值時,第二列是以升序排列的。如果第一列中有些值爲 nulls 時,情況也是這樣的.

where

  • 條件查詢子句
select * from 表名 where 條件

--其中條件: 包括一些運算符
		between A and B(包含邊界值)
		in(vlaue1,value2,value3,...)  --返回指定的字段匹配()中的值的結果.
		like 模糊查詢
		is [not] null 爲空值
運算符

在這裏插入圖片描述

like 模糊查詢中一些通配符:

% :表示一個或多個字符
_ :表示一個字符
escape :對於特殊符號可使用ESCAPE 標識符來查找

--eg.
select * from emp where sal between 1600 and 2900;
select * from emp where ename in('SMITH','CLARK','KING');
SELECT * FROM EMP WHERE ENAME LIKE '_/%%' escape '/'; --從emp表中查詢ename, 要求名字第二位帶有'%'的所有信息.
--escape後面指定的字符,表示like中第一次出現時,其後面的一位字符,原樣輸出.

Oracle中SQL函數

  • 分爲;兩類:
    -1. 單行函數
    -2. 多行函數
--單行函數: 具體有哪些自己查Google,不再贅述.
--只需知道單行函數中有:字符函數,數值函數,日期函數,轉換函數,通用函數

--多行函數; 
			sum(), avg() 只適用於數值型
			count(),max(),min() :適用於任何數據類型.
單行函數
  • 這裏只講解常用的:
轉換函數: 常用:
to_char() , to_data() , to_number() 
--其中數值類型與字符類型可以`影式`互轉,無需顯示強調.類似Java中的自動類型轉化.

1. number-->char
	--指定顯示格式:
--9表示位置佔位,例如999,999,999會將數字按照三個一組使用逗號隔開。
--L表示人民幣符號,$表示美元符號
--0可以進行佔位分組,但是如果真實數據位數不足,會使用0進行補位。

--eg.select to_char(12345,'$999,999,999') from dual;

--其中dual是 Oracle存在的僞表,是爲了方便進行數據的驗證而臨時存在的表.

2. char-->date
--使用to_date('要轉換的字符',日期格式)函數將字符轉換爲日期
--字符必須符合日期格式,常用格式:
			--yyyy-mm-dd
			-- yyyy/mm/dd

3. date-->char
--使用to_char('要轉換的日期',轉換格式)
--如果不指名轉換格式,則使用默認格式,

========================================================================

其他函數
1. nvl(字段名,新的值):如果字段值不爲null,則返回該字段的值。如果爲null則返回新的值.
2. nvl2(字段名,處理1,處理2):如果字段值不爲null,則執行處理1,爲null執行處理2
3. decode(字段名,值1,處理1,值2,處理2,值3,處理3,...,公共處理)
          --如果字段的值和decode中的條件值相同則執行對象的處理。如果都沒有則執行公共處理
多行函數
--除count(*)外,其餘函數都是跳過null,處理非空值.
--可以使用nvl()多函數強制限制處理空值.
select count(nvl(field,0)) form table....;

count():
--count(*) 返回表的記錄數
--count(字段名) 返回非空值的數量
--count(distinct 字段名) 去除重複後的字段值的數量

--小結:
- 多行函數(max,min,avg,sum,count)很重要
- 多行函數:不能與其他字段混用,.因爲多行函數的值只有一個(從多行中選取最合適的值)而字段這是所有行, 不能一一對應.除非分組.
- 多行函數不能和單行函數,普通字段混用,除非分組.
- 多行函數和與多行函數混用.

group by

--使用`group by` ,`select`後的字段只能是`分組的字段`和`多行函數`
--關鍵字:group by 分組字段名,分組字段名....
--注意1:使用了分組後,在select語句中只允許出現分組字段和多行函數
--注意2:如果是多字段分組,則先按照第一字段分組,然後每個小組繼續按照二個字段繼續分組,以此類推。
--注意3:在where子句中不允許出現多行函數。因爲不符合邏輯.

having

--分組篩選
--關鍵字:having
--作用:針對分組進行分組後的數據篩選,允許使用多行函數。
--注意:having關鍵必須和分組結合使用。不允許單獨使用。   
--where和having的比較:
--where子句不允許出現多行函數,having允許出現多行函數
--where子句和having都可以使用普通字段直接進行篩選,但是where的效率高於having
--where執行順序: from--->where--->group by-->select-->order by
--having執行順序:from--->group by-->select--->having--->order by
--結論:在分組語句中,使用where進行字段級別的篩選,使用having進行多行函數的篩選

--執行過程:
from--where--group by--select--having--order by

eg. SELECT JOB,COUNT(*) FROM EMP GROUP BY JOB;
--分析: 先從from開始,選擇表emp,然後執行where(沒有), 然後執行group by 按照job分組: 然後統計每組中個數.即執行select中的語句.最後進行排序 orderby (沒有) .

--我覺得講的可以了吧,覺得還行的扣111. 

insert into

insert into 表名(字段名,字段名,...)values(值1,值2,值3....);

--注意1:主鍵必須給值,允許爲空的字段可以不給值。
--注意2:插入語句表名後跟的字段名爲要賦值的字段,值和字段數量和順序必須是一一對應的。
--注意3:如果是全字段插入,可以省略字段名部分 insert into 表名 values(值1,值2,.....)

delete from

delete from 表名 刪除表中的所有記錄
delete from 表名 where 條件 刪除指定的數據,只要符合條件就會刪除

truncate table 表名  刪除表中的所有記錄,但是效率高於deletetruncate table 表名  刪除表中的所有記錄,但是效率高於delete

update

--update 表名 set 字段名=新的值,字段名=新的值...(會將字段的值全部改爲新的值)
--update 表名 set 字段名=新的值,字段名=新的值... where 條件(將符合條件的數據的字段改爲新的值)

多表聯合查詢(最後的榮光,堅持吧! 勇士)

  • 簡介: SQL92 和 SQL99
  • 都可以用, 具體用哪個,隨你.
- SQL92方式(92年標準)---不帶全外連接
- SQL99方式(99年標準)

連接方式:`笛卡爾積`,`等值鏈接`, `不等值連接`,` 自連接`. , `外連接` 
SQL92
--笛卡爾積:將多個表的數據進行一一對應,所得到結果爲多表的笛卡爾積。
--結果的數量爲所有表的數量的乘積

--等值連接篩選
--概念:先做表的笛卡爾積,然後篩選,篩選條件爲等值篩選。
--注意:條件爲字段的值相同來進行篩選,字段的名字可以不同
--等值連接,是要一個字段沒有值`null` ,會被篩選掉,但想要的話必須用外連接

--不等值連接 : 將等值連接的'=' 轉化爲非等號.

--自連接: 
--查詢員工姓名,工作,薪資,及上級領導姓名
select e1.ename,e1.job,e1.sal,e2.ename from emp e1,emp e2 	where e1.mgr=e2.empno
--注意: 自連接特徵: 一般有兩個字段值相同, 名字無所謂.

--其實,總的來說,上述所見,都可以歸結於等值連接的變種.具體情況具體分析即可.

========================================================================

外連接: 何爲外連接?
--由來: 因爲上述連接,查詢的都是非空字段,null字段自動過濾,但是成年人不要選擇,我全都要,這樣的話如何爲之?
--解決: 採用外連接: 即可

分類: 左外連接,右外連接
首先強調: 
SELECT *FROM EMP e,DEPT d WHERE e.DEPTNO=d.DEPTNO;
--這個statement中結果集的字段順序是,先e表中的所有字段,然後是d中的所有字段.所以左表是e,右表是d.

左外連接: 左表爲基準,就是左表的屬性全部顯示,然後顯示右表符合條件的字段.包含null.
右外連接: 類似上面,以右表爲基準,全部顯示, 左表只顯示與條件相符合的字段.

符號'+': 根據語義,左外連接,就是將'+' 放在左表之外的右表上.
						右外連接: 就是將'+' 放在右表之外,左表上.	
						
	--猜一猜下面的statement是什麼連接?  請回答!!!
	SELECT *FROM EMP e,DEPT d WHERE e.DEPTNO(+)=d.DEPTNO;
SQL99
--笛卡爾積:使用cross join 關鍵字
---select 內容 from 表名 cross join 表名2


--自然連接:使用關鍵字 natural join
--使用:select 內容 from 表名 natural join 表名
--特點1:底層先笛卡爾積,然後按照''所有的同名同值''字段自動進行等值篩選

--問題1:如果只想按照部分字段結果篩選怎麼辦?--using
--問題2:如果想按照字段名不同,但是值相同進行等值篩選怎麼辦?--on 

--解決1:使用using關鍵字
--作用1:指明使用指定的字段對聯合查詢的結果進行等值篩選
	--注意:指明的字段必須是兩表的同名同值字段
	--使用:select 內容 from 表名 inner join 表名 using(字段名,字段名,....);

--解決2:使用on關鍵字進行自定義連接條件篩選(等值篩選,不等值篩選)
	--注意:普通篩選條件使用where進行篩選,不要使用on進行。好處:SQL語句的閱讀性變強。
	--使用:select 內容 from 表名 inner join 表名 on 連接條件 where 普通篩選條件


--自連接: 
select .. inner join .. on..where...
==========================================================

外連接:
--左外連接:select 內容 from 表名 left outer join 表名 on 連接條件 ;
--右外連接:select 內容 from 表名 right outer join 表名 on 連接條件;
--全外連接:select 內容 from 表名 full outer join 表名 on 連接條件 ;

--提示: 一般可以省略 inner 和 outer ,但是官方建議寫出具體語義會好些.

這裏不再贅述.與SQL92一樣,使用差不多,公式給出,就用.

子查詢(Oracle最後的關卡,收官之戰)

--單行子查詢:
  --使用時機:篩選條件不明確需要執行一次查詢,並且查詢結果一個字段並值只有一個
  --注意:where子句中允許出現查詢語句,該查詢語句稱爲子查詢
  --使用:select 內容 from 表名 where 字段名 比較運算符 子查詢語句

 --多行子查詢
  --使用:子查詢的結果只有一個字段但是字段有n個值,考慮使用多行子查詢,其實就是使用關鍵字

		--關鍵字1:any 任意
		--select 內容 from 表名 where 字段名 比較運算符 any 子查詢語句
		
		--關鍵字2:all 所有
		--select 內容 from 表名 where 字段名 比較運算符 all 子查詢語句
		
		--關鍵字3:(not)in 表示任意存在,相當於 = any
		--select 內容 from 表名 where 字段名 in 子查詢語句   
	    --select 內容 from 表名 where 字段名 not in 子查詢語句   

Oracle篇暫時完結. MySQL會更新.莫得急~~~

四. MySQL 篇

)

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