面試系列之——數據庫知識(2)

MySQL數據庫在5.0版本後開始支持存儲過程,那麼什麼是存儲過程呢?怎麼創建、查看和刪除存儲過程呢?存儲過程有什麼優點?這些是本章節要探討的問題:
什麼是存儲過程:
簡單的說存儲過程是爲了完成某個數據庫中的特定功能而編寫的語句集,該語句集包括SQL語句(對數據的增刪改查)、條件語句和循環語句等。
創建存儲過程:
存儲過程的創建非常簡單,其創建結構爲:

CREATE PROCEDURE proc_name ([proc_parameter[,...]])  
[characteristic] 
routine_body
  • 1
  • 2
  • 3

說明:
proc_name代表存儲過程名稱;
proc_parameter代表存儲過程參數列表。該列表中的每個參數由3部分組成,即輸入輸出類型、參數名稱和參數類型。其形式如下: [ IN | OUT | INOUT ] param_name type ,其中[ IN | OUT | INOUT ]表示輸出類型(IN表示輸入參數;OUT表示輸出參數; INOUT表示既可以是輸入,也可以是輸出。輸入輸出類型也可以去掉,默認爲in); param_name表示參數名稱(注意:MySQL數據庫存儲過程的參數名前不允許“@”,SQL Server數據庫中可以);type表示參數類型,該類型可以是MySQL數據庫的任意數據類型。

注意:MySQL數據庫存儲過程不需要在參數列表括號後面“as”關鍵字,但SQL Server數據庫中的存儲過程必須加“as”關鍵字。

characteristic指定存儲過程的特性;該參數有多個值:
1.LANGUAGE SQL:說明routine_body部分是由SQL語言的語句組成,數據庫系統默認值。
2.[NOT] DETERMINISTIC:指明存儲過程的執行結果是否是確定的。DETERMINISTIC表示結果是確定的,這時當每次執行存儲過程時相同的輸入會得到相同的輸出。NOT DETERMINISTIC表示結果是非確定的,這時相同的輸入可能得到不同的輸出。默認爲非確定。
3. { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }:指明子程序使用SQL語句的限制。CONTAINS SQL表示子程序包含SQL語句,但不包含讀或寫數據的語句;NO SQL表示子程序中不包含SQL語句;READS SQL DATA表示子程序中包含讀數據的語句;MODIFIES SQL DATA表示子程序中包含寫數據的語句。默認爲CONTAINS SQL。
4.SQL SECURITY { DEFINER | INVOKER }:指明誰有權限來執行。DEFINER表示只有定義者自己才能夠執行;INVOKER表示調用者可以執行。默認爲DEFINER。
5.COMMENT ‘string’:存儲過程註釋信息。
6. routine_body參數爲存儲過程體,BEGIN…END標誌存儲過程體的開始和結束。存儲過程體可以是SELECT、UPDATE、INSERT、DELETE、CREATE TABLE等SQL語句,也可以嵌入調用其它存儲過程的代碼,還可以是其它代碼(參見博客:《數據庫中的控制語句》)。

注意:不能在 MySQL 存儲過程中使用 “return” 關鍵字。

存儲過程優點
1、存儲過程增強了SQL語言靈活性。存儲過程可以使用控制語句編寫,可以完成複雜的判斷和較複雜的運算,有很強的靈活性;
2、減少網絡流量,降低了網絡負載。存儲過程在數據庫服務器端創建成功後,只需要調用該存儲過程即可,而傳統的做法是每次都將大量的SQL語句通過網絡發送至數據庫服務器端然後再執行;
3、存儲過程只在創造時進行編譯,以後每次執行存儲過程都不需再重新編譯,而一般SQL語句每執行一次就編譯一次,所以使用存儲過程可提高數據庫執行速度。
4、系統管理員通過設定某一存儲過程的權限實現對相應的數據的訪問權限的限制,避免了非授權用戶對數據的訪問,保證了數據的安全。

存儲過程可參考:存儲過程詳解

2.數據庫的三級模式

數據庫的三級模式結構是指:數據庫系統是由外模式、模式和內模式三級構成,如下所示:
在這裏插入圖片描述

  • 1.模式(Schema)
    模式也稱爲:邏輯模式,它是DB中全體數據的邏輯結構和特徵的描述,是所有用戶的公共數據視圖。模式層是數據庫模式結構的中間層,既不涉及到數據的物理存儲細節和硬件環境,也與具體的應用程序、應用開發工具以及高級程序設計語言無關(C、C++、JAVA等)。
    模式就是數據庫數據在邏輯上的視圖,且一個數據庫只有一個模式。實際工作中,模式就等同於程序員創建一個具體的數據庫的全部操作,如:這是一個MySQL數據庫,有2張表,每個表的名字,屬性的名字、類型、取值範圍,主鍵,外鍵,索引,其他完整性約束等等。
    DBMS提供模式描述語言(模式DDL)來嚴格地定義模式。
  • 2.外模式
    外模式也稱爲:子模式(subschema)/用戶模式,它是數據庫用戶(應用程序員、最終用戶)能夠看到的使用的局部數據的邏輯結構和特徵的描述,是數據庫的數據視圖,是與某一個應用有關的數據的邏輯表示
    外模式通常是模式的子集。一個數據庫可以有多個外模式。同一個外模式可以爲某一用戶的多個應用系統所使用,但一個應用系統只能使用一個外模式。
    外模式是保證數據庫安全性的一個有力措施。每個用戶只能看見和訪問所對應的外模式中的數據,數據庫中的其餘數據是不可見的。
    DBMS提供子模式描述語言(子模式DDL)來嚴格地定義子模式。
  • 3.內模式
    內模式也稱爲:存儲模式(Storage schema),一個數據庫只有一個內模式。它是數據庫物理結構和存儲方式的描述,是數據在數據庫內部的表示方式。如:記錄的存儲方式是堆存儲,還是按照某些屬性值的升(降)存儲,還是按照屬性值聚簇(cluster)存儲;索引按照什麼方式組織,是B+樹索引,還是hash索引等等。
    DBMS提供內模式描述語言(內模式DDL/存儲模式DDL)來嚴格定義內模式。

二級映像功能和數據的獨立性
數據庫的3級模式是對數據的3個抽象級別。它使得用戶能夠邏輯地抽象地處理數據,而不必再去關心數據在計算機中的具體表示方式與存儲方式。實際上,爲了能夠實現在這3個抽象層次之間的聯繫和轉換,DBMS在這三級模式之間設計了兩層映像:
外模式/模式映像
模式/內模式映像
這兩層映像保證了數據庫中的數據能夠具有較高的邏輯獨立性和物理獨立性。
1. 外模式/模式映像
由上可知:一個DB只有一個模式,但可以有多個外模式。
所以,對於每一個外模式,數據庫系統都有一個外模式/模式映像,它定義了這個外模式與模式的對應關係。外模式的描述中通常包含了這些映像的定義。
當模式改變時(增加新的關係、新的屬性、改變屬性的數據類型等),由數據庫管理員對各個外模式/模式映像作相應的改變,可以使得外模式保持不變。而又由於應用程序應該是依據外模式編寫的,從而應用程序不必修改,這就保證了數據與程序的邏輯獨立性。
總結:外模式/模式映像保證了當模式改變時,外模式不用變 — 邏輯獨立性。
2. 模式/內模式映像
由上可知:一個DB只有一個模式,也只有一個內模式,所有模式/內模式映像是唯一的,它定義了數據全局邏輯結構與存儲結構之間的對應關係。
當數據庫的存儲結構改變時(例如選用了另一個存儲結構),由數據庫管理員對模式/內模式映像作出相應的改變,可以使得模式保持不變,從而應用程序也不必改變。這就保證了數據和程序的物理獨立性。
總結:模式/內模式映像保證了當內模式改變時,模式不用變 — 物理獨立性。

3.在mysql中,字段類型中的char,varchar,blob,text的區別?

它們的存儲方式和數據的檢索方式都不一樣。

  • char:存儲定長數據很方便(最多不可以超過255字符),CHAR字段上的索引效率級高,必須在括號裏定義長度,可以有默認值,比如定義char(10),那麼不論你存儲的數據是否達到了10個字節,都要佔去10個字節的空間(自動用空格填充),且在檢索的時候後面的空格會隱藏掉,所以檢索出來的數據需要記得用什麼trim之類的函數去過濾空格。
  • varchar:存儲變長數據(最多不可以超過65535字節),但存儲效率沒有CHAR高,必須在括號裏定義長度,可以有默認值。保存數據的時候,不進行空格自動填充,而且如果數據存在空格時,當值保存和檢索時尾部的空格仍會保留。另外,varchar類型的實際長度是它的值的實際長度+1,這一個字節用於保存實際使用了多大的長度。
  • BLOB被視爲二進制字符串,BLOB列沒有字符集,並且排序和比較基於列值字節的數值值,在大多數方面,可以將BLOB列視爲能夠足夠大的VARBINARY列
  • text:存儲可變長度的非Unicode數據,最大長度爲2^31-1個字符。text列不能有默認值,存儲或檢索過程中,不存在大小寫轉換,後面如果指定長度,不會報錯誤,但是這個長度是不起作用的,意思就是你插入數據的時候,超過你指定的長度還是可以正常插入。

結論
(1)經常變化的字段用varchar;
(2)知道固定長度的用char;
(3)儘量用varchar;
(4)超過255字節的只能用varchar或者text;
(5)能用varchar的地方不用text;
(6)能夠用數字類型的字段儘量選擇數字類型而不用字符串類型的(電話號碼),這會降低查詢和連接的性能,並會增加存儲開銷。這是因爲引擎在處理查詢和連接回逐個比較字符串中每一個字符,而對於數字型而言只需要比較一次就夠;
(7)如果是要存儲二進制流的內容(比如圖片),那麼可以採取用Blob;

4.什麼情況下應該對字段建立索引?

1.經常查詢的字段;
2.唯一性強的字段,比如像性別字段,區分度不大,所以不適合建立;
3.出現在where條件查詢的字段,因爲如果不會出現在where字段之後,那麼建立索引也就沒有必要了;出現在where條件查詢的字段,因爲如果不會出現在where字段之後,那麼建立索引也就沒有必要了;
4.不經常修改的字段,因爲對於經常修改的字段,那麼還要進行索引的維護,這是需要消耗時間和空間;不經常修改的字段,因爲對於經常修改的字段,那麼還要進行索引的維護,這是需要消耗時間和空間;
5.不會出現null值的字段;

5.字段存在索引但是會發現無效的情況有哪些?

1.進行了模糊匹配,使用"%Like"
2.使用了or查詢,兩端的字段某個不存在索引
3.進行了函數操作字段,比如abs()函數進行了函數操作字段,比如abs()函數
4.對字段進行了運算,比如使用!= 或者< ,>等對字段進行了運算,比如使用!= 或者< ,>等
5.對於Bolb和text字段,只能使用前綴索引對於Bolb和text字段,只能使用前綴索引
6.join條件字段類型不一致的時候join條件字段類型不一致的時候
7.對於字段出現null的情況,並且這種字段是不適合建立索引對於字段出現null的情況,並且這種字段是不適合建立索引

6.數據庫中的內連接,外連接,交叉連接?

答:內連接:內連接查詢操作列出與連接條件匹配的數據行,它使用比較運算符比較被連接列的列值。(下面三種)

  • 1.等值連接:在連接條件中使用等於號(=)運算符比較被連接列的列值,其查詢結果中列出被連接表中的所有列,包括其中的重複列。
  • 2.不等值連接:在連接條件使用除等於運算符以外的其它比較運算符比較被連接的列的列值。這些運算符包括>、>=、<=、<、!>、!<和<>。不等值連接:在連接條件使用除等於運算符以外的其它比較運算符比較被連接的列的列值。這些運算符包括>、>=、<=、<、!>、!<和<>。
  • 3.自然連接:在連接條件中使用等於(=)運算符比較被連接列的列值,但它使用選擇列表指出查詢結果集合中所包括的列,並刪除連接表中的重複列。自然連接:在連接條件中使用等於(=)運算符比較被連接列的列值,但它使用選擇列表指出查詢結果集合中所包括的列,並刪除連接表中的重複列。

內連接sql語句具體實現可使用下面兩種方式,其中第二種方式的inner可以省略。

select * from book as a,stu as b where a.sutid = b.stuid

select * from book as a inner join stu as b on a.sutid = b.stuid

  • 1
  • 2
  • 3

外鏈接

  • 4.左聯接:是以左表爲基準,將a.stuid = b.stuid的數據進行連接,然後將左表沒有的對應項顯示,右表的列爲NULL左聯接:是以左表爲基準,將a.stuid = b.stuid的數據進行連接,然後將左表沒有的對應項顯示,右表的列爲NULL
select * from book as a left join stu as b on a.sutid = b.stuid
  • 1
  • 5.右連接:是以右表爲基準,將a.stuid = b.stuid的數據進行連接,然以將右表沒有的對應項顯示,左表的列爲NULL右連接:是以右表爲基準,將a.stuid = b.stuid的數據進行連接,然以將右表沒有的對應項顯示,左表的列爲NULL
select * from book as a right join stu as b on a.sutid = b.stuid
  • 1
  • 6.全連接:完整外部聯接返回左表和右表中的所有行。當某行在另一個表中沒有匹配行時,則另一個表的選擇列表列包含空值。如果表之間有匹配行,則整個結果集行包含基表的數據值;(注意:在mysql中是不支持這種方式的,而只能通過先左連接,然後使用union all 再與右連接的方式)
select * from book as a full outer join stu as b on a.sutid = b.stuid
  • 1

交叉連接

  • 7.交叉連接:交叉聯接返回左表中的所有行,左表中的每一行與右表中的所有行組合。交叉聯接也稱作笛卡爾積。交叉連接:交叉聯接返回左表中的所有行,左表中的每一行與右表中的所有行組合。交叉聯接也稱作笛卡爾積。
select * from book as a full outer join stu as b on a.sutid = b.stuid
  • 1

具體的例子:https://www.cnblogs.com/zxlovenet/p/4005256.html
在這裏插入圖片描述

7.數據庫的安全性如何保證?

設置用戶的權限:保證非法用戶的非法侵入;
定義視圖:通過這樣把不同權限用戶所能看到的數據和操作的數據進行隔離;
數據加密:保證數據的保密性;數據加密:保證數據的保密性;
啓動事務管理和故障恢復:防止意外情況的發生,保證數據的一致性和完整性,主要的措施是日誌記錄和數據複製;啓動事務管理和故障恢復:防止意外情況的發生,保證數據的一致性和完整性,主要的措施是日誌記錄和數據複製;
數據庫備份和恢復:防止數據非法丟失和意外情況發現,保證數據可進行一定恢復;數據庫備份和恢復:防止數據非法丟失和意外情況發現,保證數據可進行一定恢復;
審計追蹤機制:主要是對於數據的更新,刪除操作進行日誌記錄,方便後續的審查;審計追蹤機制:主要是對於數據的更新,刪除操作進行日誌記錄,方便後續的審查;
加強服務器的安全:因爲數據庫都是存放在服務器中的,所以需要保證服務器的安全;加強服務器的安全:因爲數據庫都是存放在服務器中的,所以需要保證服務器的安全;

8.說說聚集索引和非聚集索引的理解?

1.聚集索引
聚集索引表記錄的排列順序和索引的排列順序一致,所以查詢效率快,只要找到第一個索引值記錄,其餘就連續性的記錄在物理也一樣連續存放。葉子節點存儲真實的數據行,不再有另外單獨的數據頁。在一張表上只能創建一個聚集索引,因爲真實數據的物理順序只能有一種,若一張表沒有聚集索引,則它被稱爲堆集,這樣表的數據行無特定的順序,所有新行將被添加到表的末尾。聚集索引可以是一列(單索引的時候)或者是多列(組合索引的時候)。但是,聚集索引對應的缺點就是修改慢,因爲爲了保證表中記錄的物理和索引順序一致,在記錄插入的時候,會對數據頁重新排序。

2.非聚集索引
非聚集索引制定了表中記錄的邏輯順序,但是記錄的物理和索引不一定一致,兩種索引都採用B+樹結構,非聚集索引的葉子層並不和實際數據頁相重疊,而採用葉子層包含一個指向表中的記錄在數據頁中的指針方式。非聚集索引層次多,不會造成數據重排。

用例子對比兩種索引:
聚集索引就類似新華字典中的拼音排序索引,都是按順序進行,例如找到字典中的“愛”,就裏面順序執行找到“癌”。而非聚集索引則類似於筆畫排序,索引順序和物理順序並不是按順序存放的。還可以類比,聚集索引就是電話薄是根據字母順序進行排列,而非聚集索引可以類比爲書的目錄,雖然頁的索引的在一起,但是索引帶有指針纔是真正指向數據的存儲位置。

非聚集索引和聚集索引的區別
(1)葉子節點並非數據節點
(2)葉子節點爲每一個真正的數據行存儲一個"鍵-指針"對
(3)葉子節點中還存儲了一個指針偏移量,根據頁指針及指針偏移可以定位到具體的數據行
(4)在除葉子節點外的其他索引節點,存儲的是類似內容,只不過是指向下一級索引頁

8.請說說對於分頁操作你是如何做的?

比如,我現在需要找到產品表中的第800000條數據後面的20條數據。
(1)直接通過limit start count分頁語句,形如 select * from product limit start, count
比如:select * from product limit 800000 , 20
缺點:通過通過這樣的方法的話,當數據表的數據非常多的時候,效率非常慢
總結:
1:limit語句的查詢時間與起始記錄的位置成正比。start越大,速度越慢。
2:mysql的limit語句是很方便,但是對記錄很多的表並不適合直接使用。

(2)利用表的覆蓋索引來加速分頁查詢
我們都知道,利用了索引查詢的語句中如果只包含了那個索引列(覆蓋索引),那麼這種情況會查詢很快。
所以,有兩種方法進行優化。
方法一:通過id >= 的形式。
原因:因爲,在每個表中,列表項id基本都是主鍵,所以,這是符合覆蓋索引查詢的加速優化的條件的。
SELECT * FROM product WHERE ID > =(select id from product limit 800000 ,1) limit 20
方法二:通過join操作
SELECT * FROM product a JOIN (select id from product limit 800000 , 20) b ON a.ID = b.id

9.數據庫select語句的完整執行順序是什麼?(重要)

(1)from子句組裝來自不同數據源的數據
(2)where子句基於指定的條件對記錄進行篩選
(3)group by 子句將數據劃分爲多個分組
(4)使用聚集函數進行計算
(5)使用having子句篩選分組
(6)計算所有的表達式
(7)select的字段
(8)使用order by 對結果集進行排序
(9)limit進行篩選對應的條目數量

以上每個步驟都會產生一個虛擬表,該虛擬表被用作下一個步驟的輸入,這些虛擬表對調用者(客戶端應用程序或者外部查詢)不可用。只有最後一步生成的表纔會給調用者。如果沒有在查詢中指定某一個子句,將跳過相應的步驟。

10.Mysql數據庫架構中各個模塊的作用是什麼?(重要)

在這裏插入圖片描述
1.連接管理與安全驗證
每個客戶端都會建立一個與服務器連接的線程,服務器會有一個線程池來管理這些連接,如果客戶端需要連接到mysql數據庫還需要進行驗證,包括用戶名,密碼,主機信息等

2.解析器
解析器的作用主要是分析查詢語句,最終生成解析樹;首先解析器會對查詢語句的語法進行分析,分析語法是否有問題。還有解析器會查詢緩存,如果在緩存中有對應的語句,就返回查詢結果不進行接下來的優化執行操作。前提是緩存中的數據沒有被修改,當然如果被修改了也會被清出緩存。

3.優化器
優化器的作用主要是對查詢語句進行優化操作,包括選擇合適的索引,數據的讀取方式,包括獲取查詢的開銷信息,統計信息等,這也是爲什麼圖中會有優化器指向存儲引擎的箭頭。個人感覺,因爲又花錢需要通過存儲引擎獲取查詢的大致數據和統計信息。

4.執行器
執行器包括執行查詢語句,返回查詢結果,生成執行計劃包括與存儲引擎的一些處理操作。

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