數(shù)據(jù)庫范式及MYSQL優(yōu)化整體思路
一、數(shù)據(jù)庫范式
為了建立冗余較小、結(jié)構(gòu)合理的數(shù)據(jù)庫,設(shè)計(jì)數(shù)據(jù)庫時(shí)必須遵循一定的規(guī)則。在關(guān)系型數(shù)據(jù)庫中這種規(guī)則就稱為范式。范式是符合某一種設(shè)計(jì)要求的總結(jié)。要想設(shè)計(jì)一個(gè)結(jié)構(gòu)合理的關(guān)系型數(shù)據(jù)庫,必須滿足一定的范式。
1.1、第一范式(1NF:每一列不可包含多個(gè)值)
所謂第一范式(1NF)是指數(shù)據(jù)庫表的每一列都是不可分割的基本數(shù)據(jù)項(xiàng),同一列中不能有多個(gè)值,即實(shí)體中的某個(gè)屬性不能有多個(gè)值或者不能有重復(fù)的屬性。如果出現(xiàn)重復(fù)的屬性,就可能需要定義一個(gè)新的實(shí)體,新的實(shí)體由重復(fù)的屬性構(gòu)成,新實(shí)體與原實(shí)體之間為一對多關(guān)系。在第一范式(1NF)中表的每一行只包含一個(gè)實(shí)例的信息。
在任何一個(gè)關(guān)系數(shù)據(jù)庫中,第一范式(1NF)是對關(guān)系模式的基本要求,不滿足第一范式(1NF)的數(shù)據(jù)庫就不是關(guān)系數(shù)據(jù)庫。
1.2、第二范式(2NF:非主屬性部分依賴于主關(guān)鍵字)
第二范式(2NF)是在第一范式(1NF)的基礎(chǔ)上建立起來的,即滿足第二范式(2NF)必須先滿足第一范式(1NF)。第二范式(2NF)要求數(shù)據(jù)庫表中的每個(gè)實(shí)例或行必須可以被唯一地區(qū)分。為實(shí)現(xiàn)區(qū)分通常需要為表加上一個(gè)列,以存儲各個(gè)實(shí)例的唯一標(biāo)識。
第二范式(2NF)要求實(shí)體的屬性完全依賴于主關(guān)鍵字。所謂完全依賴是指不能存在僅依賴主關(guān)鍵字一部分的屬性,如果存在,那么這個(gè)屬性和主關(guān)鍵字的這一部分應(yīng)該分離出來形成一個(gè)新的實(shí)體,新實(shí)體與原實(shí)體之間是一對多的關(guān)系。為實(shí)現(xiàn)區(qū)分通常需要為表加上一個(gè)列,以存儲各個(gè)實(shí)例的唯一標(biāo)識。簡而言之,第二范式就是非主屬性部分依賴于主關(guān)鍵字。
1.3、第三范式(3NF:屬性不依賴于其它非主屬性)
滿足第三范式(3NF)必須先滿足第二范式(2NF)。簡而言之,第三范式(3NF)要求一個(gè)數(shù)據(jù)庫表中不包含已在其它表中已包含的非主關(guān)鍵字信息。例如,存在一個(gè)部門信息表,其中每個(gè)部門有部門編號、部門名稱、部門簡介等信息。那么在員工信息表中列出部門編號后就不能再將部門名稱、部門簡介等與部門有關(guān)的信息再加入員工信息表中。如果不存在部門信息表,則根據(jù)第三范式(3NF)也應(yīng)該構(gòu)建它,否則就會(huì)有大量的數(shù)據(jù)冗余。簡而言之,第三范式就是屬性不依賴于其它非主屬性。
1.4、反三范式(反3NF:為了性能,增加冗余)
3NF提出目的是為了降低冗余,減少不必要的存儲,這對于存儲設(shè)備昂貴的過去是很有必要的,但是隨著存儲設(shè)備的降價(jià)以及人們對性能的不斷提高,又有人提出反三范式。
所謂反三范式就是為了性能,增加冗余。以部門信息表為例,每個(gè)部門有部門編號、部門名稱、部門簡介等信息,按照3NF的要求,為了避免冗余,我們在員工表中就不應(yīng)該加入部門名稱、部門簡介等部門有關(guān)信息,帶來的代價(jià)是每次都要查詢兩次數(shù)據(jù)庫。反三范式允許我們?nèi)哂嘀匾畔⒌絾T工表中,例如部門名稱,這樣我們每次取員工信息時(shí)就能直接取出部門名稱,不需要查詢兩次數(shù)據(jù)庫,提升了程序性能。
二、MYSQL優(yōu)化整體思路
MYSQL優(yōu)化首先應(yīng)該定位問題,可能導(dǎo)致MYSQL低性能的原因有:業(yè)務(wù)邏輯過多的查詢、表結(jié)構(gòu)不合理、sql語句優(yōu)化以及硬件優(yōu)化,從優(yōu)化效果來看,這四個(gè)優(yōu)化點(diǎn)的優(yōu)化效果依次降低:理清業(yè)務(wù)邏輯能夠幫助我們避免不必要的查詢,合理設(shè)計(jì)表結(jié)構(gòu)也能幫助我們少查詢數(shù)據(jù)庫。對于sql語句優(yōu)化,我們可以先使用慢查詢?nèi)罩径ㄎ宦樵儯缓筢槍υ摬樵冞M(jìn)行優(yōu)化,最常見且最有效的優(yōu)化范式就是增加合理的索引,這個(gè)在上篇博客已經(jīng)講解,本篇博客將講解其他一些優(yōu)化手段或者注意點(diǎn)。
2.1、謹(jǐn)慎使用TEXT/BLOB類型
當(dāng)列類型是TEXT或者BLOB時(shí),我們應(yīng)該特別注意,因?yàn)楫?dāng)選擇的字段有 text/blob 類型的時(shí)候,無法創(chuàng)建內(nèi)存表,只能創(chuàng)建硬盤臨時(shí)表,而硬盤臨時(shí)表的性能比內(nèi)存表的性能差,所以如果非要使用TEXT/BLOB類型,應(yīng)該單獨(dú)建表,不要把TEXT/BLOB類型與核心屬性混合在一張表中。對此,做一個(gè)實(shí)驗(yàn)如下:
//創(chuàng)建數(shù)據(jù)表 create table t1 ( num int, intro text(1000) ); //插入數(shù)據(jù) insert into t1 values (3,'this is USA') , (4,'China'); //查詢臨時(shí)表創(chuàng)建情況 //注意,這里Created_tmp_disk_tables=4,Created_tmp_tables=10 mysql> show status like '%tmp%'; +-------------------------+-------+ | Variable_name | Value | +-------------------------+-------+ | Created_tmp_disk_tables | 4 | | Created_tmp_files | 9 | | Created_tmp_tables | 10 | +-------------------------+-------+ //使用group by查詢數(shù)據(jù) mysql> select * from t1 group by num; +------+-------------+ | num | intro | +------+-------------+ | 3 | this is USA | | 4 | China | +------+-------------+ 2 rows in set (0.05 sec) //再次查詢臨時(shí)表創(chuàng)建情況 //現(xiàn)在,Created_tmp_disk_tables=5,Created_tmp_tables=11 mysql> show status like '%tmp%'; +-------------------------+-------+ | Variable_name | Value | +-------------------------+-------+ | Created_tmp_disk_tables | 5 | | Created_tmp_files | 9 | | Created_tmp_tables | 11 | +-------------------------+-------+ |
posted on 2014-11-07 10:29 順其自然EVO 閱讀(302) 評論(0) 編輯 收藏 所屬分類: 測試學(xué)習(xí)專欄