Mysql數據庫(二)

MySQL面試常問知識點

1.數據庫範式

  • 第一範式(1NF)

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

  • 第二範式(2NF)

    第二範式(2NF)是在第一範式(1NF)的基礎上建立起來的,即滿足第二範式(2NF)必須先滿足第一範式(1NF)。第二範式(2NF)要求數據庫表中的每個實例或行必須可以被惟一地區分。爲實現區分通常需要爲表加上一個列,以存儲各個實例的惟一標識。這個惟一屬性列被稱爲主關鍵字或主鍵、主碼。第二範式(2NF)要求實體的屬性完全依賴於主關鍵字。所謂完全依賴是指不能存在僅依賴主關鍵字一部分的屬性,如果存在,那麼這個屬性和主關鍵字的這一部分應該分離來形成一個新的實體,新實體與原實體之間是一對多的關係。爲實現區分通常需要爲表加上一個列,以存儲各個實例的惟一標識。簡而言之,第二範式就是非主屬性部分依賴於主關鍵字。EG:不能出現A->B,(A,C)->B(A決定B,A、C決定B),因爲這不是完全依賴

  • 第三範式(3NF)

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

2.多表查詢

  • 交叉連接查詢(笛卡爾乘積:4*3=12,產生笛卡爾積的原因是沒有足夠的連接條件)(一般不用)

      				需求:查詢員工及其部門名稱
    
      				SELECT employee.name,dept.name FROM employee,dept;
    
  • 內連接查詢(使用最多)

      				多表查詢的步驟:1)確定查詢哪些表
    
      				               2)確定查詢哪些字段
    
      				               3)確定連接條件(規則:條件=表數量-1)
    
      				SELECT employee.name,dept.name FROM employee,dept WHERE employee.deptId=dept.id;
    
      				另一種語法
    
      				SELECT e.name,d.name FROM employee e INNER JOIN dept d ON e.deptId=d.id;
    
  • 左外連接查詢(左表數據全部顯示,如果右邊不滿足,則顯示null)

      				需求:查詢部門及其部門的員工
    
      				SELECT d.name,e.name FROM dept d LEFT OUTER JOIN employee e ON d.id=e.deptId;
    
      		- 右外連接查詢(右表數據全部顯示,如果左邊不滿足,則顯示null)
    
      				SELECT d.name,e.name FROM employee e RIGHT OUTER JOIN dept d ON e.deptId=d.id;
    

3.主鍵 超鍵 候選鍵 外鍵

  • 超鍵(super key) :在關係中能唯一標識元組的屬性集稱爲關係模式的超鍵

  • 候選鍵(candidate key):不含有多餘屬性的超鍵稱爲候選鍵

  • 主鍵(primary key):用戶選作元組標識的一個候選鍵程序主鍵

  • 外鍵(foreign key):如果關係模式R1中的某屬性集不是R1的主鍵,而是另一個關係R2的主鍵,則該屬性集是關係模式R1的外鍵

      		實例講解
    
      		假設有如下兩個表:
    
      		         學生(學號,姓名,性別,身份證號,教師編號)
    
      		         教師(教師編號,姓名,工資)
    
      		超鍵:由超鍵的定義可知,學生表中含有學號或者身份證號的任意組合都爲此表的超鍵。如:(學號)、(學號,姓名)、(身份證號,性別)等。
    
      		候選鍵:候選鍵屬於超鍵,它是最小的超鍵,就是說如果再去掉候選鍵中的任何一個屬性它就不再是超鍵了。學生表中的候選鍵爲:(學號)、(身份證號)。
    
      		主鍵:主鍵就是候選鍵裏面的一個,是人爲規定的,例如學生表中,我們通常會讓“學號”做主鍵,教師表中讓“教師編號”做主鍵。
    
      		外鍵:外鍵比較簡單,學生表中的外鍵就是“教師編號”。外鍵主要是用來描述兩個表的關係。
    

4.數據庫事務

  • 數據庫事務,是由有限的數據庫操作序列組成的邏輯執行單元,這一系列操作要麼全部執行,要麼全部放棄執行。

  • 數據庫事務transanction正確執行的四個基本要素:ACID,原子性(Atomicity)、一致性(Correspondence)、隔離性(Isolation)、持久性(Durability)。

    • 原子性:整個事務中的所有操作,要麼全部完成,要麼全部不完成,不可能停滯在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣

    • 一致性:在事務開始之前和事務結束以後,數據庫的完整性約束沒有被破壞。

    • 隔離性:隔離狀態執行事務,使它們好像是系統在給定時間內執行的唯一操作。如果有兩個事務,運行在相同的時間內,執行相同的功能,事務的隔離性將確保每一事務在系統中認爲只有該事務在使用系統。這種屬性有時稱爲串行化,爲了防止事務操作間的混淆,必須串行化或序列化請求,使得在同一時間僅有一個請求用於同一數據。

    • 持久性:在事務完成以後,該事務所對數據庫所作的更改便持久的保存在數據庫之中,並不會被回滾。

5.視圖

  • 視圖是虛擬的表,與包含數據的表不一樣,視圖只包含使用時動態檢索數據的查詢;不包含任何列或數據。使用視圖可以簡化複雜的sql操作,隱藏具體的細節,保護數據;視圖創建後,可以使用與表相同的方式利用它們。

  • 視圖不能被索引,也不能有關聯的觸發器或默認值,如果視圖本身內有order by 則對視圖再次order by將被覆蓋

    創建視圖:create view XXX as XXXXXXXXXXXXXX;(刪除也是類似的)

  • 於某些視圖比如未使用聯結子查詢分組聚集函數Distinct Union等,是可以對其更新的,對視圖的更新將對基表進行更新;

  • 但是視圖主要用於簡化檢索,保護數據,並不用於更新,而且大部分視圖都不可以更新。

6.drop,delete與truncate的區別

drop直接刪掉表;truncate刪除表中數據,再插入時自增長id又從1開始 ;delete刪除表中數據,可以加where字句。

  • DELETE語句執行刪除的過程是每次從表中刪除一行,並且同時將該行的刪除操作作爲事務記錄在日誌中保存以便進行進行回滾操作。TRUNCATE TABLE 則一次性地從表中刪除所有的數據並不把單獨的刪除操作記錄記入日誌保存,刪除行是不能恢復的。並且在刪除的過程中不會激活與表有關的刪除觸發器。執行速度快。

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

  • 一般而言,drop > truncate > delete

  • 應用範圍。TRUNCATE 只能對TABLE;DELETE可以是table和view

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

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

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

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

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

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

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

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

7.索引的工作原理及其種類

  • 數據庫索引,是數據庫管理系統中一個排序的數據結構,以協助快速查詢、更新數據庫表中數據。索引的實現通常使用B樹及其變種B+樹。在數據之外,數據庫系統還維護着滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法。這種數據結構,就是索引。

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

  • 使用:

    • create index 索引名 on 表名(列名)

    • drop index 索引名;

    • 索引優點

      1)通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。

      2)可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。

      3)可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。

      4)在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。

      5)通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。

    • 索引缺點

      1)創建索引和維護索引要耗費時間,這種時間隨着數據量的增加而增加。

      2)索引需要佔物理空間,除了數據表佔數據空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。

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

    • 建議創建索引列

      1)在經常需要搜索的列上,可以加快搜索的速度;

      2)在作爲主鍵的列上,強制該列的唯一性和組織表中數據的排列結構;

      3)在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;

      4)在經常需要根據範圍進行搜索的列上創建索引,因爲索引已經排序,其指定的範圍是連續的;在經常需要排序的列上創建索引,因爲索引已經排序,這樣查詢可以利用索引的排序, 加快排序查詢時間;

      5)在經常使用在WHERE子句中的列上面創建索引,加快條件的判斷速度。

    • 不建議創建索引列

    1) 對於那些在查詢中很少使用或者參考的列不應該創建索引。這是因爲,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。

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

    3) 對於那些定義爲text, image和bit數據類型的列不應該增加索引。這是因爲,這些列的數據量要麼相當大,要麼取值很少。

    4) 當修改性能遠遠大於檢索性能時,不應該創建索引。這是因爲,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引。

    • 索引分類

      • 唯一索引:唯一索引是不允許其中任何兩行具有相同索引值的索引。

        當現有數據中存在重複的鍵值時,大多數數據庫不允許將新創建的唯一索引與表一起保存。數據庫還可能防止添加將在表中創建重複鍵值的新數據。例如,如果在employee表中職員的姓(lname)上創建了唯一索引,則任何兩個員工都不能同姓。

      • 主鍵索引

        數據庫表經常有一列或列組合,其值唯一標識表中的每一行。該列稱爲表的主鍵。 在數據庫關係圖中爲表定義主鍵將自動創建主鍵索引,主鍵索引是唯一索引的特定類型。該索引要求主鍵中的每個值都唯一。當在查詢中使用主鍵索引時,它還允許對數據的快速訪問。

      • 聚集索引

        在聚集索引中,表中行的物理順序與鍵值的邏輯(索引)順序相同。一個表只能包含一個聚集索引。如果某索引不是聚集索引,則表中行的物理順序與鍵值的邏輯順序不匹配。與非聚集索引相比,聚集索引通常提供更快的數據訪問速度。

    • 局部性原理與磁盤預讀

      • 由於存儲介質的特性,磁盤本身存取就比主存慢很多,再加上機械運動耗費,磁盤的存取速度往往是主存的幾百分分之一,因此爲了提高效率,要儘量減少磁盤I/O。爲了達到這個目的,磁盤往往不是嚴格按需讀取,而是每次都會預讀,即使只需要一個字節,磁盤也會從這個位置開始,順序向後讀取一定長度的數據放入內存。這樣做的理論依據是計算機科學中著名的局部性原理:當一個數據被用到時,其附近的數據也通常會馬上被使用。程序運行期間所需要的數據通常比較集中。

      • 由於磁盤順序讀取的效率很高(不需要尋道時間,只需很少的旋轉時間),因此對於具有局部性的程序來說,預讀可以提高I/O效率。預讀的長度一般爲頁(page)的整倍數。頁是計算機管理存儲器的邏輯塊,硬件及操作系統往往將主存和磁盤存儲區分割爲連續的大小相等的塊,每個存儲塊稱爲一頁(在許多操作系統中,頁的大小通常爲4k),主存和磁盤以頁爲單位交換數據。當程序要讀取的數據不在主存中時,會觸發一個缺頁異常,此時系統會向磁盤發出讀盤信號,磁盤會找到數據的起始位置並向後連續讀取一頁或幾頁載入內存中,然後異常返回,程序繼續運行。

    • 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作爲索引結構效率是非常高的。

8.數據庫優化的思路

  • 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 只會在檢索出所有記錄之後纔對結果集進行過濾

  • 索引優化

    看上文索引

  • 數據庫結構優化

    1)範式優化: 比如消除冗餘(節省空間。。)

    2)反範式優化:比如適當加冗餘等(減少join)

    3)拆分表: 垂直拆分和水平拆分

  • 服務器硬件優化

    這個麼多花錢咯!

9.MySql的複製原理以及流程(主從複製)

基本原理流程,3個線程以及之間的關聯;(主節點、從節點)
1) 主:binlog線程——記錄下所有改變了數據庫數據的語句,放進master上的binlog中;

2) 從:io線程——在使用start slave 之後,負責從master上拉取 binlog 內容,放進自己的relay log中;

3) 從:sql執行線程——執行relay log中的語句;

10.MySQL中myisam與innodb的區別,至少5點

			1)InnoDB支持事物,而MyISAM不支持事物

			2)InnoDB支持行級鎖,而MyISAM支持表級鎖

			3)InnoDB支持MVCC(多版本併發控制), 而MyISAM不支持

			4)InnoDB支持外鍵,而MyISAM不支持

			5)InnoDB不支持全文索引,而MyISAM支持。

11.innodb引擎的4大特性

			插入緩衝(insert buffer)、二次寫(double write)、自適應哈希索引(ahi)、預讀(read ahead)

12.兩者select count(*)哪個更快,爲什麼

			myisam更快,因爲myisam內部維護了一個計數器,可以直接調取。

13.MySQL中varchar與char的區別以及varchar(50)中的50代表的涵義

1)varchar與char的區別

char是一種固定長度的類型,varchar則是一種可變長度的類型

2)varchar(50)中50的涵義

最多存放50個字符,varchar(50)和(200)存儲hello所佔空間一樣,但後者在排序時會消耗更多內存,因爲order by col採用fixed_length計算col長度(memory引擎也一樣)

3)int(20)中20的涵義

指顯示字符的長度,但要加參數的,最大爲255,比如它是記錄行數的id,插入10筆資料,它就顯示00000000001 ~~~00000000010,當字符的位數超過11,它也只顯示11位,如果你沒有加那個讓它未滿11位就前面加0的參數,它不會在前面加0。20表示最大顯示寬度爲20,但仍佔4字節存儲,存儲範圍不變;

14.innodb的事務與日誌的實現方式

			1)有多少種日誌

			       錯誤日誌:記錄出錯信息,也記錄一些警告信息或者正確的信息。

			       查詢日誌:記錄所有對數據庫請求的信息,不論這些請求是否得到了正確的執行

			       慢查詢日誌:設置一個閾值,將運行時間超過該值的所有SQL語句都記錄到慢查詢的日誌文件中。

			       二進制日誌:記錄對數據庫執行更改的所有操作。

			       中繼日誌

			       事務日誌:

			2)事物的4種隔離級別

			       讀未提交(RU)

			       讀已提交(RC)

			       可重複讀(RR)

			       串行

			3)事務是如何通過日誌來實現的

			       事務日誌是通過redo和innodb的存儲引擎日誌緩衝(Innodb log buffer)來實現的,當開始一個事務的時候,會記錄該事務的lsn(log sequence number)號; 
			       當事務執行時會往InnoDB存儲引擎的日誌的日誌緩存裏面插入事務日誌;當事務提交時,必須將存儲引擎的日誌緩衝寫入磁盤(通過innodb_flush_log_at_trx_commit來控制),也就是寫數據前,需要先寫日誌。這種方式稱爲“預寫日誌方式”。

15.關於兩種引擎的介紹

  • Innodb引擎,Innodb引擎提供了對數據庫ACID事務的支持。並且還提供了行級鎖和外鍵的約束。它的設計的目標就是處理大數據容量的數據庫系統。它本身實際上是基於Mysql後臺的完整的系統。Mysql運行的時候,Innodb會在內存中建立緩衝池,用於緩衝數據和索引。但是,該引擎是不支持全文搜索的。同時,啓動也比較的慢,它是不會保存表的行數的。當進行Select count(*) from table指令的時候,需要進行掃描全表。所以當需要使用數據庫的事務時,該引擎就是首選。由於鎖的粒度小,寫操作是不會鎖定全表的。所以在併發度較高的場景下使用會提升效率的。

  • MyIASM引擎,它是MySql的默認引擎,但不提供事務的支持,也不支持行級鎖和外鍵。因此當執行Insert插入和Update更新語句時,即執行寫操作的時候需要鎖定這個表。所以會導致效率會降低。不過和Innodb不同的是,MyIASM引擎是保存了表的行數,於是當進行Select count(*) from table語句時,可以直接的讀取已經保存的值而不需要進行掃描全表。所以,如果表的讀操作遠遠多於寫操作時,並且不需要事務的支持的。可以將MyIASM作爲數據庫引擎的首先。

    補充2點:

    • 大容量的數據集時趨向於選擇Innodb。因爲它支持事務處理和故障的恢復。Innodb可以利用數據日誌來進行數據的恢復。主鍵的查詢在Innodb也是比較快的。

    • 大批量的插入語句時(這裏是INSERT語句)在MyIASM引擎中執行的比較的快,但是UPDATE語句在Innodb下執行的會比較的快,尤其是在併發量大的時候。

16.兩種引擎所使用的索引的數據結構是什麼?

  • 都是B+樹!

  • MyIASM引擎,B+樹的數據結構中存儲的內容實際上是實際數據的地址值。也就是說它的索引和實際數據是分開的,只不過使用索引指向了實際數據。這種索引的模式被稱爲非聚集索引。

  • Innodb引擎的索引的數據結構也是B+樹,只不過數據結構中存儲的都是實際的數據,這種索引有被稱爲聚集索引。

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