1. 程式人生 > >mysql的一些問題詳解

mysql的一些問題詳解

1.資料庫事務的四個特性及含義

資料庫事務transanction正確執行的四個基本要素。ACID,原子性(Atomicity)、一致性(Correspondence)、隔離性(Isolation)、永續性(Durability)。

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

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

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

永續性:在事務完成以後,該事務所對資料庫所作的更改便持久的儲存在資料庫之中,並不會被回滾。

2.檢視的作用,檢視可以更改麼?

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

檢視不能被索引,也不能有關聯的觸發器或預設值,如果檢視本身內有order by 則對檢視再次order by將被覆蓋。

建立檢視:create view XXX as XXXXXXXXXXXXXX;

對於某些檢視比如未使用聯結子查詢分組聚集函式Distinct Unio

3.資料庫正規化

1 第一正規化(1NF)

在任何一個關係資料庫中,第一正規化(1NF)是對關係模式的基本要求,不滿足第一正規化(1NF)的資料庫就不是關係資料庫。

所謂第一正規化(1NF)是指資料庫表的每一列都是不可分割的基本資料項,同一列中不能有多個值,即實體中的某個屬性不能有多個值或者不能有重複的屬性。如果出現重複的屬性,就可能需要定義一個新的實體,新的實體由重複的屬性構成,新實體與原實體之間為一對多關係。在第一正規化(1NF)中表的每一行只包含一個例項的資訊。簡而言之,第一正規化就是無重複的列。

2 第二正規化(2NF)

第二正規化(2NF)是在第一正規化(1NF)的基礎上建立起來的,即滿足第二正規化(2NF)必須先滿足第一正規化(1NF)。第二正規化(2NF)要求資料庫表中的每個例項或行必須可以被惟一地區分。為實現區分通常需要為表加上一個列,以儲存各個例項的惟一標識。這個惟一屬性列被稱為主關鍵字或主鍵、主碼。

第二正規化(2NF)要求實體的屬性完全依賴於主關鍵字。所謂完全依賴是指不能存在僅依賴主關鍵字一部分的屬性,如果存在,那麼這個屬性和主關鍵字的這一部分應該分離出來形成一個新的實體,新實體與原實體之間是一對多的關係。為實現區分通常需要為表加上一個列,以儲存各個例項的惟一標識。簡而言之,第二正規化就是非主屬性非部分依賴於主關鍵字。

3 第三正規化(3NF)

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

4.資料庫優化的思路

這個我借鑑了慕課上關於資料庫優化的課程。

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上(女的愛購物 哈哈)

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

觸發器與儲存過程非常相似,觸發器也是SQL語句集,兩者唯一的區別是觸發器不能用EXECUTE語句呼叫,而是在使用者執行Transact-SQL語句時自動觸發(啟用)執行。觸發器是在一個修改了指定表中的資料時執行的儲存過程。通常通過建立觸發器來強制實現不同表中的邏輯相關資料的引用完整性和一致性。由於使用者不能繞過觸發器,所以可以用它來強制實施複雜的業務規則,以確保資料的完整性。觸發器不同於儲存過程,觸發器主要是通過事件執行觸發而被執行的,而儲存過程可以通過儲存過程名稱名字而直接呼叫。當對某一表進行諸如UPDATE、INSERT、DELETE這些操作時,SQLSERVER就會自動執行觸發器所定義的SQL語句,從而確保對資料的處理必須符合這些SQL語句所定義的規則。

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

(1)、問5點不同;

1>.InnoDB支援事物,而MyISAM不支援事物

2>.InnoDB支援行級鎖,而MyISAM支援表級鎖

3>.InnoDB支援MVCC, 而MyISAM不支援

4>.InnoDB支援外來鍵,而MyISAM不支援

5>.InnoDB不支援全文索引,而MyISAM支援。

(2)、innodb引擎的4大特性

(2)、innodb引擎的4大特性

插入緩衝(insert buffer),二次寫(double write),自適應雜湊索引(ahi),預讀(read ahead)

(3)、2者selectcount(*)哪個更快,為什麼

(3)、2者selectcount(*)哪個更快,為什麼

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

7.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位元組儲存,儲存範圍不變;

(4)、mysql為什麼這麼設計

對大多數應用沒有意義,只是規定一些工具用來顯示字元的個數;int(1)和int(20)儲存和計算均一樣;

8、問了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來控制),也就是寫資料前,需要先寫日誌。這種方式稱為“預寫日誌方式”

9、sql優化

(1)、explain出來的各種item的意義;

select_type

表示查詢中每個select子句的型別

type

表示MySQL在表中找到所需行的方式,又稱“訪問型別”

possible_keys

指出MySQL能使用哪個索引在表中找到行,查詢涉及到的欄位上若存在索引,則該索引將被列出,但不一定被查詢使用

key

顯示MySQL在查詢中實際使用的索引,若沒有使用索引,顯示為NULL

key_len

表示索引中使用的位元組數,可通過該列計算查詢中使用的索引的長度

ref

表示上述表的連線匹配條件,即哪些列或常量被用於查詢索引列上的值

Extra

包含不適合在其他列中顯示但十分重要的額外資訊

(2)、profile的意義以及使用場景;

查詢到 SQL 會執行多少時間, 並看出 CPU/Memory 使用量, 執行過程中 Systemlock, Table lock 花多少時間等等

10.一個6億的表a,一個3億的表b,通過外間tid關聯,你如何最快的查詢出滿足條件的第50000到第50200中的這200條資料記錄。

一個6億的表a,一個3億的表b,通過外間tid關聯,你如何最快的查詢出滿足條件的第50000到第50200中的這200條資料記錄。

1、如果A表TID是自增長,並且是連續的,B表的ID為索引

select * from a,b where a.tid = b.id and a.tid>500000 limit 200;

2、如果A表的TID不是連續的,那麼就需要使用覆蓋索引.TID要麼是主鍵,要麼是輔助索引,B表ID也需要有索引。

select * from b , (select tid from a limit 50000,200) a where b.id = a .tid;

  1. 主鍵 超鍵 候選鍵 外來鍵

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

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

3)主鍵(primary key):使用者選作元組標識的一個候選鍵程式主鍵

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

12、 對於關係型資料庫而言,索引是相當重要的概念,請回答有關索引的幾個問題:

a)、索引的目的是什麼?

快速訪問資料表中的特定資訊,提高檢索速度

建立唯一性索引,保證資料庫表中每一行資料的唯一性。

加速表和表之間的連線

使用分組和排序子句進行資料檢索時,可以顯著減少查詢中分組和排序的時間

b)、索引對資料庫系統的負面影響是什麼?

負面影響:

建立索引和維護索引需要耗費時間,這個時間隨著資料量的增加而增加;索引需要佔用物理空間,不光是表需要佔用資料空間,每個索引也需要佔用物理空間;當對錶進行增、刪、改、的時候索引也要動態維護,這樣就降低了資料的維護速度。

c)、為資料表建立索引的原則有哪些?

在最頻繁使用的、用以縮小查詢範圍的欄位上建立索引。

在頻繁使用的、需要排序的欄位上建立索引

d)、 什麼情況下不宜建立索引?

對於查詢中很少涉及的列或者重複值比較多的列,不宜建立索引。

對於一些特殊的資料型別,不宜建立索引,比如文字欄位(text)等

13.什麼是儲存過程

儲存過程是一些編譯好的SQL語句

因為系統在呼叫SQL的時候比較浪費時間,所以之前先將一些基本的額SQL語句程式碼進行編譯(對單表或多表的增刪改查),然後再給程式碼取一個名字,在需要這個功能時去呼叫它就可以了。

優缺點

儲存工程是編譯後的程式碼 效率高

儲存過程代替SQL語句,降低網路通訊

在一定的程度確保資料安全

14.資料庫中的樂觀鎖和悲觀鎖

根據不同型別可以對資料設定不同的鎖許可權

** 樂觀 悲觀 鎖 主要是作用在併發訪問控制**

悲觀鎖 假定會發生併發衝突,遮蔽任何違反資料完整的操作

樂觀鎖 假定不會發生衝突,只有在提交操作時檢查是否違反資料的完整性