數據庫常見面試題講解

一、觸發器的做用?
觸發器是一中特殊的存儲過程,主要是經過事件來觸發而被執行的。它能夠強化約束,來維護數據的完整性和一致性,能夠跟蹤數據庫內的操做從而不容許未經許可的更新和變化。能夠聯級運算。如,某表上的觸發器上包含對另外一個表的數據操做,而該操做又會致使該表觸發器被觸發。
二、什麼是存儲過程?用什麼來調用?
存儲過程是一個預編譯的SQL語句,優勢是容許模塊化的設計,就是說只需建立一次,之後在該程序中就能夠調用屢次。若是某次操做須要執行屢次SQL,使用存儲過程比單純SQL語句執行要快。 調用: 1)能夠用一個命令對象來調用存儲過程。 2)能夠供外部程序調用,好比:java程序。
三、存儲過程的優缺點?
優勢: 1)存儲過程是預編譯過的,執行效率高。 2)存儲過程的代碼直接存放於數據庫中,經過存儲過程名直接調用,減小網絡通信。 3)安全性高,執行存儲過程須要有必定權限的用戶。 4)存儲過程能夠重複使用,可減小數據庫開發人員的工做量。 缺點:移植性差
四、存儲過程與函數的區別
存儲過程 函數
用於在數據庫中完成特定的操做或者任務(如插入、刪除等) 用於特定的數據(如選擇)
程序頭部聲明用procedure 程序頭部聲明用function
程序頭部聲明時不需描述返回類型 程序頭部聲明時要描述返回類型,並且PL/SQL塊中至少要包括一個有效的return語句
可使用in/out/in out 三種模式的參數 可使用in/out/in out 三種模式的參數
可做爲一個獨立的PL/SQL語句來執行 不能獨立執行,必須做爲表達式的一部分調用
能夠經過out/in out 返回零個或多個值 經過return語句返回一個值,且改值要與聲明部分一致,也能夠是經過out類型的參數帶出的變量
SQL語句(DML 或SELECT)中不可調用存儲過程 SQL語句(DML 或SELECT)中能夠調用函數
五、索引的做用?和它的優勢缺點是什麼?
索引就一種特殊的查詢表,數據庫的搜索能夠利用它加速對數據的檢索。它很相似與現實生活中書的目錄,不須要查詢整本書內容就能夠找到想要的數據。索引能夠是惟一的,建立索引容許指定單個列或者是多個列。缺點是它減慢了數據錄入的速度,同時也增長了數據庫的尺寸大小。
六、什麼樣的字段適合建索引
惟1、不爲空、常常被查詢的字段
七、索引類型有哪些?
邏輯上:
Single column 單行索引
Concatenated 多行索引
Unique 惟一索引
NonUnique 非惟一索引
Function-based 函數索引
Domain 域索引 物理上:
Partitioned 分區索引
NonPartitioned 非分區索引
B-tree :
Normal 正常型B樹
Rever Key 反轉型B樹 Bitmap 位圖索引
八、什麼是事務?什麼是鎖?
事務就是被綁定在一塊兒做爲一個邏輯工做單元的SQL語句分組,若是任何一個語句操做失敗那麼整個操做就被失敗,之後操做就會回滾到操做前狀態,或者是上有個節點。爲了確保要麼執行,要麼不執行,就可使用事務。要將有組語句做爲事務考慮,就須要經過ACID測試,即原子性,一致性,隔離性和持久性。 鎖:在因此的DBMS中,鎖是實現事務的關鍵,鎖能夠保證事務的完整性和併發性。與現實生活中鎖同樣,它可使某些數據的擁有者,在某段時間內不能使用某些數據或數據結構。固然鎖還分級別的。
九、什麼叫視圖?遊標是什麼?
視圖:是一種虛擬的表,具備和物理表相同的功能。能夠對視圖進行增,改,查,操做,試圖一般是有一個表或者多個表的行或列的子集。對視圖的修改會影響基本表。它使得咱們獲取數據更容易,相比多表查詢。 遊標:是對查詢出來的結果集做爲一個單元來有效的處理。遊標能夠定在該單元中的特定行,從結果集的當前行檢索一行或多行。能夠對結果集當前行作修改。通常不使用遊標,可是須要逐條處理數據的時候,遊標顯得十分重要。
十、視圖的優缺點
優勢: 1)對數據庫的訪問,由於視圖能夠有選擇性的選取數據庫裏的一部分。 2 )用戶經過簡單的查詢能夠從複雜查詢中獲得結果。 3 )維護數據的獨立性,試圖可從多個表檢索數據。 4 )對於相同的數據可產生不一樣的視圖。 缺點: 性能:查詢視圖時,必須把視圖的查詢轉化成對基本表的查詢,若是這個視圖是由一個複雜的多表查詢所定義,那麼,那麼就沒法更改數據
十一、列舉幾種錶鏈接方式,有什麼區別?
內鏈接、自鏈接、外鏈接(左、右、全)、交叉鏈接 內鏈接:只有兩個元素表相匹配的才能在結果集中顯示。 外鏈接: 左外鏈接:左邊爲驅動表,驅動表的數據所有顯示,匹配表的不匹配的不會顯示。 右外鏈接:右邊爲驅動表,驅動表的數據所有顯示,匹配表的不匹配的不會顯示。 全外鏈接:鏈接的表中不匹配的數據所有會顯示出來。 交叉鏈接: 笛卡爾效應,顯示的結果是連接表數的乘積。
十二、主鍵和外鍵的區別?
主鍵在本表中是惟一的、不可惟空的,外鍵能夠重複能夠惟空;外鍵和另外一張表的主鍵關聯,不能建立對應表中不存在的外鍵。
1三、在數據庫中查詢語句速度很慢,如何優化?
1.建索引 2.減小表之間的關聯 3.優化sql,儘可能讓sql很快定位數據,不要讓sql作全表查詢,應該走索引,把數據 量大的表排在前面 4.簡化查詢字段,沒用的字段不要,已經對返回結果的控制,儘可能返回少許數據 5.儘可能用PreparedStatement來查詢,不要用Statement
1四、數據庫三範式是什麼?
第一範式:列不可再分 第二範式:行能夠惟一區分,主鍵約束 第三範式:表的非主屬性不能依賴與其餘表的非主屬性 外鍵約束 且三大範式是一級一級依賴的,第二範式創建在第一範式上,第三範式創建第一第二範式上
1五、union和union all有什麼不一樣?
UNION在進行表連接後會篩選掉重複的記錄,因此在表連接後會對所產生的結果集進行排序運算,刪除重複的記錄再返回結果。實際大部分應用中是不會產生重複的記錄,最多見的是過程表與歷史表UNION。 UNION ALL只是簡單的將兩個結果合併後就返回。這樣,若是返回的兩個結果集中有重複的數據,那麼返回的結果集就會包含重複的數據了。 從效率上說,UNION ALL 要比UNION快不少,因此,若是能夠確認合併的兩個結果集中不包含重複的數據的話,那麼就使用UNION ALL。
1六、Varchar2和varchar有什麼區別?
Char的長度是固定的,而varchar2的長度是能夠變化的,好比,存儲字符串「abc」對於char(20),表示你存儲的字符將佔20個字節,包含17個空,而一樣的varchar2(20)只佔了3個字節,20只是最大值,當你存儲的字符小於20時,按實際長度存儲。 char的效率要被varchar2的效率高。 目前varchar是varchar2的同義詞,工業標準的varchar類型能夠存儲空字符串,可是oracle不能這樣作,儘管它保留之後這樣作的權利。Oracle本身開發了一個數據類型varchar2,這個類型不是一個標準的varchar,他將在數據庫中varchar列能夠存儲空字符串的特性改成存儲null值,若是你想有向後兼容的能力,oracle建議使用varchar2而不是varchar
1七、Oracle和Mysql的區別?
1)庫函數不一樣。 2)Oracle是用表空間來管理的,Mysql不是。 3)顯示當前全部的表、用戶、改變鏈接用戶、顯示當前鏈接用戶、執行外部腳本的語句的不一樣。 4)分頁查詢時候時候,mysql用limit oracle用rownum
mysql> SELECT * FROM table LIMIT 5,10; // 檢索記錄行 6-15 //爲了檢索從某一個偏移量到記錄集的結束全部的記錄行,能夠指定第二個參數爲 -1: mysql> SELECT * FROM tableLIMIT 95,-1; // 檢索記錄行 96-last. //若是隻給定一個參數,它表示返回最大的記錄行數目: mysql> SELECT * FROM table LIMIT 5; //檢索前 5 個記錄行 //換句話說,LIMIT n 等價於 LIMIT 0,n。 5)sql的語法的不一樣。java

1八、Oracle語句有多少類型
Oracle語句分三類:DDL、DML、DCL。 DDL(Data Definition Language)數據定義語言,包括: Create語句:能夠建立數據庫和數據庫的一些對象。 Drop語句:能夠刪除數據表、索引、觸發程序、條件約束以及數據表的權限等。 Alter語句:修改數據表定義及屬性。 Truncate語句:刪除表中的全部記錄,包括全部空間分配的記錄被刪除。 DML(Data Manipulation Language)數據操控語言,包括: Insert語句:向數據表張插入一條記錄。 Delete語句:刪除數據表中的一條或多條記錄,也能夠刪除數據表中的全部記錄,可是它的操做對象還是記錄。 Update語句:用於修改已存在表中的記錄的內容。 DCL(Data Control Language)數據庫控制語言,包括: Grant語句:容許對象的建立者給某用戶或某組或全部用戶(PUBLIC)某些特定的權限。 Revoke語句:能夠廢除某用戶或某組或全部用戶訪問權限
1九、oracle分頁查詢語句
使用rownum,兩種以下: 第一種: select * from (select t.*,rownum row_num from mytable t) b where b.row_num between 1 and 10 第二種: select * from ( select a.*, rownum rn from mytable a where rownum <= 10 ) where rn >= 1 使用rowid, 以下: select * from scott.emp where rowid in (select rd from (select rowid as rd ,rownum as rn from scott.emp ) where rn<=6 and rn>3)
20、從數據庫中隨機取50條
select * from (select * from t_example order by dbms_random.random) where rownum <= 50
2一、order by與group by的區別
order by 排序查詢、asc升序、desc降序 group by 分組查詢、having 只能用於group by子句、做用於組內,having條件子句能夠直接跟函數表達式。使用group by 子句的查詢語句須要使用聚合函數。
2二、commit在哪裏會運用
oracle的commit就是DML語句提交數據(這裏是釋放鎖不是鎖表),在未提交前你前面的操做更新的都是內存,沒有更新到物理文件中。 執行commit從用戶角度講就是更新到物理文件了,事實上commit時尚未寫date file,而是記錄了redo log file,要從內存寫到data物理文件,須要觸發檢查點,由DBWR這個後臺進程來寫,這裏內容有點多的,若是不深究的話你就理解成commit即爲從內存更新到物理文件。
2三、行轉列、列換行怎麼轉
1)使用decode函數 2)使用case when語句
2四、什麼是PL/SQL?
PL/SQL是一種程序語言,叫作過程化SQL語言(Procedural Language/SQL)。PL/SQL是Oracle數據庫對SQL語句的擴展。在普通SQL語句的使用上增長了編程語言的特色,因此PL/SQL把數據操做和查詢語句組織在PL/SQL代碼的過程性單元中,經過邏輯判斷、循環等操做實現複雜的功能或者計算。PL/SQL 只有 Oracle 數據庫有。 MySQL 目前不支持 PL/SQL 的。
2五、序列的做用
Oracle使用序列來生成惟一編號,用來處理一個表中自增字段。 Oracle序列是原子對象,而且是一致的。也就是說,一旦您訪問一個序列號,Oracle將在處理下一個請求以前自動遞增下一個編號,從而確保不會出現重複值。
2六、表和視圖的關係
視圖其實就是一條查詢sql語句,用於顯示一個或多個表或其餘視圖中的相關數據。 表就是關係數據庫中實際存儲數據用的。
2七、oracle基本數據類型
1)字符串類型 char、nchar、varchar、varchar二、nvarchar2 2)數字類型 number、integer 3)浮點類型 binary_float、binary_double、float 4)日期類型 date、 timestamp 5)LOB類型 blob、clob、nclob、bfile
2八、truncate與 delete區別
TRUNCATE TABLE 在功能上與不帶 WHERE 子句的 DELETE 語句相同:兩者均刪除表中的所有行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系統和事務日誌資源少。 DELETE 語句每次刪除一行,並在事務日誌中爲所刪除的每行記錄一項。
TRUNCATE TABLE 經過釋放存儲表數據所用的數據頁來刪除數據,而且只在事務日誌中記錄頁的釋放。 TRUNCATE,DELETE,DROP 放在一塊兒比較:
TRUNCATE TABLE :刪除內容、釋放空間但不刪除定義。
DELETE TABLE: 刪除內容不刪除定義,不釋放空間。
DROP TABLE :刪除內容和定義,釋放空間。
2九、oracle獲取系統時間
select to_char(sysdate, 'yyyy-MM-dd HH24:mi:ss') from dual;
30、oracle怎麼去除去重
使用distinct關鍵字
3一、如今有表:
A(id ,name,regdate) B(id,groupid) C(id,name2) 寫出下面的SQL語句 A)統計A表中每月註冊用戶數 select count(*),to_char(regdate,'yyyymm') from A group by to_char(regdate,'yyyymm'); B)統計A表中有姓名相同的用戶數 select count(*) from (select name from A group by name having count(*) >1); C)若是表A中有姓名相同的用戶,把相同的查出,寫入表C中 nsert into C(name2) select name from A group by name having count(*) >1; D)A中ID有多個相同的數據,A中姓名相同的ID只保留註冊時間最大的數據 delete from E where e.regdate < (select max(regdate) from a X where E.id = X.id);
3二、現有表:
Student(S#,SN,SD)學生表 Course(C#,CN,T#)課程表 SC(S#,C#,score)成績表 1.查詢選了課程‘稅收’的學生的學號和名字 答: select SN,SD from Student where S# in( select S# from Course C , SC where C.C#=SC.C# and CN= ’稅收基礎’); 2.查詢選課數量大於5的學生的學號和名字 答: select SN,SD from Student where S# in ( select S# from SC group by S# having count(distinct C#) > 5); ) 3.創建一個學生表students,包括name,age,head_teacher,id,score(姓名,年齡,班主任,學號,成績) Create table students ( Id number(9) not null primary key, Name varchar2(40) not null, Age int check(age between 0 and 100), Head_teacher vachar2(40), Score float ); 4.對上表插入一條記錄,姓名:張三,年齡:18,班主任:李四,學號:22 Insert into student(id,name,age,head_teacher) values(‘22’,’張三’,’18’,’李四’); 5.對上表中的age+name建立一個索引,並說明它的做用和使用方法 Create index student_index on students(age,name);
3三、怎樣把這樣一個表(表名:tmp_table_201307)
year month amount 2012 1 1.1 2012 2 1.2 2012 3 1.3 2012 4 1.4 2012 4 1.6 2013 1 2.1 2013 2 2.2 2013 2 2.2 2013 3 2.3  2013 4 2.4   查成這樣一個結果   year m1 m2 m3 m4   2012 1.1 1.2 1.3 3   2013 2.1 4.4 2.3 2.4   Select   year,   Sum(case when month = 1 then amount else 0 end) as m1,   Sum(case when month = 2 then amount else 0 end) as m2,   Sum(case when month = 3 then amount else 0 end) as m3,   Sum(case when month = 4 then amount else 0 end) as m4   From tmp_table_201307 a   Group by year   Order by 1;
3四、數據庫中有一張表ismg_icp_flow,結構以下
SQL> desc ismg_icp_flow Name Null Type ———————————————————————————————— ICPNO NOT NULL VARCHAR2(6) SERVICE_ID NOT NULL VARCHAR2(10) STAT_MIN NOT NULL DATETIME MT_RECV_OK NOT NULL NUMBER(10) 請寫出一條SQL語句同時知足如下3個條件: 計算MT_RECV_OK的總和(顯示爲total),並以此對結果集進行升序排序 以ICPNO和SERVICE_ID兩個字段進行分組 所得出數據的STAT_MIN必須爲大於2003年1月1號0時0分而且小於2003 年2月1號0時0分 指望的輸出結果以下: ICPNO SERVICE_ID TOTAL ———— —————— ———————————— 901001 7700 271965 901001 7800 3857795 答: select ICPNO,SERVICE_ID,sum(MT_RECV_OK) TOTAL from ismg_icp_flow where STAT_MIN between to_date('2003-1-1','yyyy-mm-dd') and to_date('2003-2-1','yyyy-mm-dd') group by ICPNO,SERVICE_ID order by TOTAL;

node

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------mysql

 

1. 主鍵 超鍵 候選鍵 外鍵

主 鍵:算法

數據庫表中對儲存數據對象予以惟一和完整標識的數據列或屬性的組合。一個數據列只能有一個主鍵,且主鍵的取值不能缺失,即不能爲空值(Null)。sql

超 鍵:數據庫

在關係中能惟一標識元組的屬性集稱爲關係模式的超鍵。一個屬性能夠爲做爲一個超鍵,多個屬性組合在一塊兒也能夠做爲一個超鍵。超鍵包含候選鍵和主鍵。編程

候選鍵:安全

是最小超鍵,即沒有冗餘元素的超鍵。服務器

外 鍵:網絡

在一個表中存在的另外一個表的主鍵稱此表的外鍵。

2.數據庫事務的四個特性及含義

數據庫事務transanction正確執行的四個基本要素。ACID,原子性(Atomicity)、一致性(Correspondence)、隔離性(Isolation)、持久性(Durability)。 
原子性:整個事務中的全部操做,要麼所有完成,要麼所有不完成,不可能停滯在中間某個環節。事務在執行過程當中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務歷來沒有執行過同樣。 
一致性:在事務開始以前和事務結束之後,數據庫的完整性約束沒有被破壞。 
隔離性:隔離狀態執行事務,使它們好像是系統在給定時間內執行的惟一操做。若是有兩個事務,運行在相同的時間內,執行 相同的功能,事務的隔離性將確保每一事務在系統中認爲只有該事務在使用系統。這種屬性有時稱爲串行化,爲了防止事務操做間的混淆,必須串行化或序列化請 求,使得在同一時間僅有一個請求用於同一數據。 
持久性:在事務完成之後,該事務所對數據庫所做的更改便持久的保存在數據庫之中,並不會被回滾。

3.視圖的做用,視圖能夠更改麼?

視圖是虛擬的表,與包含數據的表不同,視圖只包含使用時動態檢索數據的查詢;不包含任何列或數據。使用視圖能夠簡化複雜的sql操做,隱藏具體的細節,保護數據;視圖建立後,可使用與表相同的方式利用它們。 
視圖不能被索引,也不能有關聯的觸發器或默認值,若是視圖自己內有order by 則對視圖再次order by將被覆蓋。 
建立視圖:create view XXX as XXXXXXXXXXXXXX; 
對於某些視圖好比未使用聯結子查詢分組彙集函數Distinct Union等,是能夠對其更新的,對視圖的更新將對基表進行更新;可是視圖主要用於簡化檢索,保護數據,並不用於更新,並且大部分視圖都不能夠更新。

4.drop,delete與truncate的區別

drop直接刪掉表 truncate刪除表中數據,再插入時自增加id又從1開始 delete刪除表中數據,能夠加where字句。 
(1) DELETE語句執行刪除的過程是每次從表中刪除一行,而且同時將該行的刪除操做做爲事務記錄在日誌中保存以便進行進行回滾操做。TRUNCATE TABLE 則一次性地從表中刪除全部的數據並不把單獨的刪除操做記錄記入日誌保存,刪除行是不能恢復的。而且在刪除的過程當中不會激活與表有關的刪除觸發器。執行速度快。

(2) 表和索引所佔空間。當表被TRUNCATE 後,這個表和索引所佔用的空間會恢復到初始大小,而DELETE操做不會減小表或索引所佔用的空間。drop語句將表所佔用的空間全釋放掉。

(3) 通常而言,drop > truncate > delete

(4) 應用範圍。TRUNCATE 只能對TABLE;DELETE能夠是table和view

(5) TRUNCATE 和DELETE只刪除數據,而DROP則刪除整個表(結構和數據)。

(6) truncate與不帶where的delete :只刪除數據,而不刪除表的結構(定義)drop語句將刪除表的結構被依賴的約束(constrain),觸發器(trigger)索引(index);依賴於該表的存儲過程/函數將被保留,但其狀態會變爲:invalid。

(7) delete語句爲DML(data maintain Language),這個操做會被放到 rollback segment中,事務提交後才生效。若是有相應的 tigger,執行的時候將被觸發。

(8) truncate、drop是DLL(data define language),操做當即生效,原數據不放到 rollback segment中,不能回滾

(9) 在沒有備份狀況下,謹慎使用 drop 與 truncate。要刪除部分數據行採用delete且注意結合where來約束影響範圍。回滾段要足夠大。要刪除表用drop;若想保留表而將表中數據刪除,若是於事務無關,用truncate便可實現。若是和事務有關,或老師想觸發trigger,仍是用delete。

(10) Truncate table 表名 速度快,並且效率高,由於: 
truncate table 在功能上與不帶 WHERE 子句的 DELETE 語句相同:兩者均刪除表中的所有行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系統和事務日誌資源少。DELETE 語句每次刪除一行,並在事務日誌中爲所刪除的每行記錄一項。TRUNCATE TABLE 經過釋放存儲表數據所用的數據頁來刪除數據,而且只在事務日誌中記錄頁的釋放。

(11) TRUNCATE TABLE 刪除表中的全部行,但表結構及其列、約束、索引等保持不變。新行標識所用的計數值重置爲該列的種子。若是想保留標識計數值,請改用 DELETE。若是要刪除表定義及其數據,請使用 DROP TABLE 語句。

(12) 對於由 FOREIGN KEY 約束引用的表,不能使用 TRUNCATE TABLE,而應使用不帶 WHERE 子句的 DELETE 語句。因爲 TRUNCATE TABLE 不記錄在日誌中,因此它不能激活觸發器。

5.索引的工做原理及其種類

數據庫索引,是數據庫管理系統中一個排序的數據結構,以協助快速查詢、更新數據庫表中數據。索引的實現一般使用B樹及其變種B+樹。

在數據以外,數據庫系統還維護着知足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就能夠在這些數據結構上實現高級查找算法。這種數據結構,就是索引。

爲表設置索引要付出代價的:一是增長了數據庫的存儲空間,二是在插入和修改數據時要花費較多的時間(由於索引也要隨之變更)。

這裏寫圖片描述

上圖展現了一種可能的索引方式。左邊是數據表,一共有兩列七條記錄,最左邊的是數據記錄的物理地址(注意邏輯上相鄰的記錄在磁盤上也並非必定物理相鄰的)。爲了加快Col2的查找,能夠維護一個右邊所示的二叉查找樹,每一個節點分別包含索引鍵值和一個指向對應數據記錄物理地址的指針,這樣就能夠運用二叉查找在O(log2n)的複雜度內獲取到相應數據。

建立索引能夠大大提升系統的性能。

第一,經過建立惟一性索引,能夠保證數據庫表中每一行數據的惟一性。

第二,能夠大大加快數據的檢索速度,這也是建立索引的最主要的緣由。

第三,能夠加速表和表之間的鏈接,特別是在實現數據的參考完整性方面特別有意義。

第四,在使用分組和排序子句進行數據檢索時,一樣能夠顯著減小查詢中分組和排序的時間。

第五,經過使用索引,能夠在查詢的過程當中,使用優化隱藏器,提升系統的性能。

也許會有人要問:增長索引有如此多的優勢,爲何不對錶中的每個列建立一個索引呢?由於,增長索引也有許多不利的方面。

第一,建立索引和維護索引要耗費時間,這種時間隨着數據量的增長而增長。

第二,索引須要佔物理空間,除了數據表佔數據空間以外,每個索引還要佔必定的物理空間,若是要創建聚簇索引,那麼須要的空間就會更大。

第三,當對錶中的數據進行增長、刪除和修改的時候,索引也要動態的維護,這樣就下降了數據的維護速度。

索引是創建在數據庫表中的某些列的上面。在建立索引的時候,應該考慮在哪些列上能夠建立索引,在哪些列上不能建立索引。通常來講,應該在這些列上建立索引:在常常須要搜索的列上,能夠加快搜索的速度;在做爲主鍵的列上,強制該列的惟一性和組織表中數據的排列結構;在常常用在鏈接的列上,這些列主要是一些外鍵,能夠加快鏈接的速度;在常常須要根據範圍進行搜索的列上建立索引,由於索引已經排序,其指定的範圍是連續的;在常常須要排序的列上建立索引,由於索引已經排序,這樣查詢能夠利用索引的排序,加快排序查詢時間;在常用在WHERE子句中的列上面建立索引,加快條件的判斷速度。

一樣,對於有些列不該該建立索引。通常來講,不該該建立索引的的這些列具備下列特色:

第一,對於那些在查詢中不多使用或者參考的列不該該建立索引。這是由於,既然這些列不多使用到,所以有索引或者無索引,並不能提升查詢速度。相反,因爲增長了索引,反而下降了系統的維護速度和增大了空間需求。

第二,對於那些只有不多數據值的列也不該該增長索引。這是由於,因爲這些列的取值不多,例如人事表的性別列,在查詢的結果中,結果集的數據行佔了表中數據行的很大比例,即須要在表中搜索的數據行的比例很大。增長索引,並不能明顯加快檢索速度。

第三,對於那些定義爲text, image和bit數據類型的列不該該增長索引。這是由於,這些列的數據量要麼至關大,要麼取值不多。

第四,當修改性能遠遠大於檢索性能時,不該該建立索引。這是由於,修改性能和檢索性能是互相矛盾的。當增長索引時,會提升檢索性能,可是會下降修改性能。當減小索引時,會提升修改性能,下降檢索性能。所以,當修改性能遠遠大於檢索性能時,不該該建立索引。

根據數據庫的功能,能夠在數據庫設計器中建立三種索引:惟一索引、主鍵索引和彙集索引。

惟一索引 
惟一索引是不容許其中任何兩行具備相同索引值的索引。

當現有數據中存在重複的鍵值時,大多數數據庫不容許將新建立的惟一索引與表一塊兒保存。數據庫還可能防止添加將在表中建立重複鍵值的新數據。例如,若是在employee表中職員的姓(lname)上建立了惟一索引,則任何兩個員工都不能同姓。 主鍵索引 數據庫表常常有一列或列組合,其值惟一標識表中的每一行。該列稱爲表的主鍵。 在數據庫關係圖中爲表定義主鍵將自動建立主鍵索引,主鍵索引是惟一索引的特定類型。該索引要求主鍵中的每一個值都惟一。當在查詢中使用主鍵索引時,它還容許對數據的快速訪問。 彙集索引 在彙集索引中,表中行的物理順序與鍵值的邏輯(索引)順序相同。一個表只能包含一個彙集索引。 
若是某索引不是彙集索引,則表中行的物理順序與鍵值的邏輯順序不匹配。與非彙集索引相比,彙集索引一般提供更快的數據訪問速度。

局部性原理與磁盤預讀 
因爲存儲介質的特性,磁盤自己存取就比主存慢不少,再加上機械運動耗費,磁盤的存取速度每每是主存的幾百分分之一,所以爲了提升效率,要儘可能減小磁盤I/O。爲了達到這個目的,磁盤每每不是嚴格按需讀取,而是每次都會預讀,即便只須要一個字節,磁盤也會從這個位置開始,順序向後讀取必定長度的數據放入內存。這樣作的理論依據是計算機科學中著名的局部性原理:當一個數據被用到時,其附近的數據也一般會立刻被使用。程序運行期間所須要的數據一般比較集中。

因爲磁盤順序讀取的效率很高(不須要尋道時間,只需不多的旋轉時間),所以對於具備局部性的程序來講,預讀能夠提升I/O效率。

預讀的長度通常爲頁(page)的整倍數。頁是計算機管理存儲器的邏輯塊,硬件及操做系統每每將主存和磁盤存儲區分割爲連續的大小相等的塊,每一個存儲塊稱爲一頁(在許多操做系統中,頁得大小一般爲4k),主存和磁盤以頁爲單位交換數據。當程序要讀取的數據不在主存中時,會觸發一個缺頁異常,此時系統會向磁盤發出讀盤信號,磁盤會找到數據的起始位置並向後連續讀取一頁或幾頁載入內存中,而後異常返回,程序繼續運行。

B-/+Tree索引的性能分析 
到這裏終於能夠分析B-/+Tree索引的性能了。

上文說過通常使用磁盤I/O次數評價索引結構的優劣。先從B-Tree分析,根據B-Tree的定義,可知檢索一次最多須要訪問h個節點。數據庫系統的設計者巧妙利用了磁盤預讀原理,將一個節點的大小設爲等於一個頁,這樣每一個節點只須要一次I/O就能夠徹底載入。爲了達到這個目的,在實際實現B-Tree還須要使用以下技巧:

每次新建節點時,直接申請一個頁的空間,這樣就保證一個節點物理上也存儲在一個頁裏,加之計算機存儲分配都是按頁對齊的,就實現了一個node只需一次I/O。

B-Tree中一次檢索最多須要h-1次I/O(根節點常駐內存),漸進複雜度爲O(h)=O(logdN)。通常實際應用中,出度d是很是大的數字,一般超過100,所以h很是小(一般不超過3)。

而紅黑樹這種結構,h明顯要深的多。因爲邏輯上很近的節點(父子)物理上可能很遠,沒法利用局部性,因此紅黑樹的I/O漸進複雜度也爲O(h),效率明顯比B-Tree差不少。

綜上所述,用B-Tree做爲索引結構效率是很是高的。

6.鏈接的種類

查詢分析器中執行: 
–建表table1,table2: 
create table table1(id int,name varchar(10)) 
create table table2(id int,score int) 
insert into table1 select 1,’lee’ 
insert into table1 select 2,’zhang’ 
insert into table1 select 4,’wang’ 
insert into table2 select 1,90 
insert into table2 select 2,100 
insert into table2 select 3,70 
如表

table1 | table2 |

id name |id score | 
1 lee |1 90| 
2 zhang| 2 100| 
4 wang| 3 70|

如下均在查詢分析器中執行 
1、外鏈接 
1.概念:包括左向外聯接、右向外聯接或完整外部聯接

2.左鏈接:left join 或 left outer join 
(1)左向外聯接的結果集包括 LEFT OUTER 子句中指定的左表的全部行,而不只僅是聯接列所匹配的行。若是左表的某行在右表中沒有匹配行,則在相關聯的結果集行中右表的全部選擇列表列均爲空值(null)。 
(2)sql 語句 
select * from table1 left join table2 on table1.id=table2.id 
————-結果————- 
idnameidscore

1lee190 
2zhang2100 
4wangNULLNULL

註釋:包含table1的全部子句,根據指定條件返回table2相應的字段,不符合的以null顯示

3.右鏈接:right join 或 right outer join 
(1)右向外聯接是左向外聯接的反向聯接。將返回右表的全部行。若是右表的某行在左表中沒有匹配行,則將爲左表返回空值。 
(2)sql 語句 
select * from table1 right join table2 on table1.id=table2.id 
————-結果————- 
idnameidscore

1lee190 
2zhang2100 
NULLNULL370

註釋:包含table2的全部子句,根據指定條件返回table1相應的字段,不符合的以null顯示

4.完整外部聯接:full join 或 full outer join 
(1)完整外部聯接返回左表和右表中的全部行。當某行在另外一個表中沒有匹配行時,則另外一個表的選擇列表列包含空值。若是表之間有匹配行,則整個結果集行包含基表的數據值。 
(2)sql 語句 
select * from table1 full join table2 on table1.id=table2.id 
————-結果————- 
idnameidscore

1lee190 
2zhang2100 
4wangNULLNULL 
NULLNULL370

註釋:返回左右鏈接的和(見上左、右鏈接)

2、內鏈接 
1.概念:內聯接是用比較運算符比較要聯接列的值的聯接

2.內鏈接:join 或 inner join

3.sql 語句 
select * from table1 join table2 on table1.id=table2.id 
————-結果————- 
idnameidscore

1lee190 
2zhang2100

註釋:只返回符合條件的table1和table2的列

4.等價(與下列執行效果相同) 
A:select a.,b. from table1 a,table2 b where a.id=b.id 
B:select * from table1 cross join table2 where table1.id=table2.id (注:cross join後加條件只能用where,不能用on)

3、交叉鏈接(徹底)

1.概念:沒有 WHERE 子句的交叉聯接將產生聯接所涉及的表的笛卡爾積。第一個表的行數乘以第二個表的行數等於笛卡爾積結果集的大小。(table1和table2交叉鏈接產生3*3=9條記錄)

2.交叉鏈接:cross join (不帶條件where…)

3.sql語句 
select * from table1 cross join table2 
————-結果————- 
idnameidscore

1lee190 
2zhang190 
4wang190 
1lee2100 
2zhang2100 
4wang2100 
1lee370 
2zhang370 
4wang370

註釋:返回3*3=9條記錄,即笛卡爾積

4.等價(與下列執行效果相同) 
A:select * from table1,table2

7.數據庫範式

1 第一範式(1NF)

在任何一個關係數據庫中,第一範式(1NF)是對關係模式的基本要求,不知足第一範式(1NF)的數據庫就不是關係數據庫。 
所謂第一範式(1NF)是指數據庫表的每一列都是不可分割的基本數據項,同一列中不能有多個值,即實體中的某個屬性不能有多個值或者不能有重複的屬性。若是出現重複的屬性,就可能須要定義一個新的實體,新的實體由重複的屬性構成,新實體與原實體之間爲一對多關係。在第一範式(1NF)中表的每一行只包含一個實例的信息。簡而言之,第一範式就是無重複的列。

2 第二範式(2NF)

第二範式(2NF)是在第一範式(1NF)的基礎上創建起來的,即知足第二範式(2NF)必須先知足第一範式(1NF)。第二範式(2NF)要求數據庫表中的每一個實例或行必須能夠被唯一地區分。爲實現區分一般須要爲表加上一個列,以存儲各個實例的唯一標識。這個唯一屬性列被稱爲主關鍵字或主鍵、主碼。 
第二範式(2NF)要求實體的屬性徹底依賴於主關鍵字。所謂徹底依賴是指不能存在僅依賴主關鍵字一部分的屬性,若是存在,那麼這個屬性和主關鍵字的這一部分應該分離出來造成一個新的實體,新實體與原實體之間是一對多的關係。爲實現區分一般須要爲表加上一個列,以存儲各個實例的唯一標識。簡而言之,第二範式就是非主屬性非部分依賴於主關鍵字。

3 第三範式(3NF)

知足第三範式(3NF)必須先知足第二範式(2NF)。簡而言之,第三範式(3NF)要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。例如,存在一個部門信息表,其中每一個部門有部門編號(dept_id)、部門名稱、部門簡介等信息。那麼在員工信息表中列出部門編號後就不能再將部門名稱、部門簡介等與部門有關的信息再加入員工信息表中。若是不存在部門信息表,則根據第三範式(3NF)也應該構建它,不然就會有大量的數據冗餘。簡而言之,第三範式就是屬性不依賴於其它非主屬性。(個人理解是消除冗餘)

8.數據庫優化的思路

這個我借鑑了慕課上關於數據庫優化的課程。 
1.SQL語句優化

1)應儘可能避免在 where 子句中使用!=或<>操做符,不然將引擎放棄使用索引而進行全表掃描。 
2)應儘可能避免在 where 子句中對字段進行 null 值判斷,不然將致使引擎放棄使用索引而進行全表掃描,如: 
select id from t where num is null 
能夠在num上設置默認值0,確保表中num列沒有null值,而後這樣查詢: 
select id from t where num=0 
3)不少時候用 exists 代替 in 是一個好的選擇 
4)用Where子句替換HAVING 子句 由於HAVING 只會在檢索出全部記錄以後纔對結果集進行過濾 
2.索引優化

看上文索引 
3.數據庫結構優化

1)範式優化: 好比消除冗餘(節省空間。。) 2)反範式優化:好比適當加冗餘等(減小join) 3)拆分表: 分區將數據在物理上分隔開,不一樣分區的數據能夠制定保存在處於不一樣磁盤上的數據文件裏。這樣,當對這個表進行查詢時,只須要在表分區中進行掃描,而沒必要進行全表掃描,明顯縮短了查詢時間,另外處於不一樣磁盤的分區也將對這個表的數據傳輸分散在不一樣的磁盤I/O,一個精心設置的分區能夠將數據傳輸對磁盤I/O競爭均勻地分散開。對數據量大的時時表可採起此方法。可按月自動建表分區。 
4)拆分其實又分垂直拆分和水平拆分: 案例: 簡單購物系統暫設涉及以下表: 1.產品表(數據量10w,穩定) 2.訂單表(數據量200w,且有增加趨勢) 3.用戶表 (數據量100w,且有增加趨勢) 以mysql爲例講述下水平拆分和垂直拆分,mysql能容忍的數量級在百萬靜態數據能夠到千萬 垂直拆分: 解決問題:表與表之間的io競爭 不解決問題:單表中數據量增加出現的壓力 方案: 把產品表和用戶表放到一個server上 訂單表單獨放到一個server上 水平拆分: 解決問題:單表中數據量增加出現的壓力 不解決問題:表與表之間的io爭奪 
方案: 用戶表經過性別拆分爲男用戶表和女用戶表 訂單表經過已完成和完成中拆分爲已完成訂單和未完成訂單 產品表 未完成訂單放一個server上 已完成訂單表盒男用戶表放一個server上 女用戶表放一個server上(女的愛購物 哈哈) 
4.服務器硬件優化

這個麼多花錢咯!

9.存儲過程與觸發器的區別

觸發器與存儲過程很是類似,觸發器也是SQL語句集,二者惟一的區別是觸發器不能用EXECUTE語句調用,而是在用戶執行Transact-SQL語句時自動觸發(激活)執行。觸發器是在一個修改了指定表中的數據時執行的存儲過程。一般經過建立觸發器來強制實現不一樣表中的邏輯相關數據的引用完整性和一致性。因爲用戶不能繞過觸發器,因此能夠用它來強制實施複雜的業務規則,以確保數據的完整性。觸發器不一樣於存儲過程,觸發器主要是經過事件執行觸發而被執行的,而存儲過程能夠經過存儲過程名稱名字而直接調用。當對某一表進行諸如UPDATE、INSERT、DELETE這些操做時,SQLSERVER就會自動執行觸發器所定義的SQL語句,從而確保對數據的處理必須符合這些SQL語句所定義的規則。

相關文章
相關標籤/搜索