- 主鍵蕉斜,外鍵猛频,超鍵,候選鍵
主鍵 | 對表中數(shù)據(jù)進行唯一標識的數(shù)據(jù)列的組合蛛勉;不能缺失鹿寻;不能空值; |
---|---|
外鍵 | 該列為另一表的主鍵诽凌; |
超鍵 | 關系中能唯一標識數(shù)據(jù)的屬性毡熏; |
候選鍵 | 不含多余屬性的超鍵; |
- 數(shù)據(jù)庫事務的四個特征及含義
原子性 | 要么全部完成侣诵,要么不完成痢法,若發(fā)生錯誤會進行回滾操作; |
---|---|
一致性 | 開始到結(jié)束后杜顺,數(shù)據(jù)庫完整性約束沒收到破壞财搁;(實體完整性,參照完整性躬络,用戶定義的完整性) |
隔離性 | 事務與事務之間相隔離尖奔,串行化執(zhí)行; |
持久性 | 事務完成對數(shù)據(jù)的影響是永久的; |
- 視圖的作用提茁,可以更改嗎
視圖是虛擬的表淹禾;只包含動態(tài)檢索數(shù)據(jù)的查詢,不包含數(shù)據(jù)茴扁;簡化操作铃岔,隱藏細節(jié),保護數(shù)據(jù)峭火;對視圖的更新會作用于基表毁习,一般不更新;
- drop,delete和truncate
drop | 表級的刪除卖丸;不能回滾纺且; |
---|---|
truncate | 清空表;不記錄單行刪除日志坯苹;無法恢復;只能對于TABLE操作摇天;不能在帶FOREIGN KEY約束的表(被引用的表)中使用粹湃;計數(shù)從頭開始; |
delete | 配合where刪除數(shù)據(jù)泉坐;會記錄日志用于回歸为鳄;會觸發(fā)觸發(fā)器;不減少索引和表的空間腕让; |
- 索引的工作原理和其種類
索引的實現(xiàn)通常采用B樹或B+樹孤钦,加快查詢速度也消耗更多空間
唯一索引 | 不允許任何兩行具相同值 |
---|---|
主鍵索引 | 唯一索引的一種 |
聚集索引 | 行的物理順序和鍵值的索引順序相同 |
普通索引 | 無限制 |
---|---|
全文索引 | 針對較大的數(shù)據(jù)生成全文索引很耗時間空間 |
組合索引 | 最左前綴原則:若對多列建立組合索引,若第二列未使用索引纯丸,則第三列也不會使用 |
InnoDB | 主索引:InnoDB的數(shù)據(jù)文件本身偏形;輔助索引:相應記錄主鍵的值 |
---|---|
MyISAM | 索引與數(shù)據(jù)分離;輔助索引:與主索引無區(qū)別觉鼻; |
- 數(shù)據(jù)庫范式
范式 | 內(nèi)容 |
---|---|
1NF | 每一列都是不可分割的基本數(shù)據(jù)項俊扭,同一列無二值;無重復的域坠陈; |
2NF | 實例依賴于主鍵部分萨惑; |
3NF | 屬性不依賴于其他非主屬性; |
首先要明確的是:滿足著第三范式仇矾,那么就一定滿足第二范式庸蔼、滿足著第二范式就一定滿足第一范式
- 第一范式:字段是最小的的單元不可再分
學生信息組成學生信息表,有年齡贮匕、性別姐仅、學號等信息組成。這些字段都不可再分,所以它是滿足第一范式的
- 第二范式:滿足第一范式,表中的字段必須完全依賴于全部主鍵而非部分主鍵萍嬉。
其他字段組成的這行記錄和主鍵表示的是同一個東西乌昔,而主鍵是唯一的,它們只需要依賴于主鍵壤追,也就成了唯一的
學號為1的同學磕道,姓名是damao,年齡是100歲行冰。姓名和年齡字段都依賴著學號主鍵溺蕉。
- 第三范式:滿足第二范式,非主鍵外的所有字段必須互不依賴
就是數(shù)據(jù)只在一個地方存儲悼做,不重復出現(xiàn)在多張表中疯特,可以認為就是消除傳遞依賴
比如,我們大學分了很多系(中文系肛走、英語系漓雅、計算機系……),這個系別管理表信息有以下字段組成:系編號朽色,系主任邻吞,系簡介,系架構(gòu)葫男。那我們能不能在學生信息表添加系編號抱冷,系主任,系簡介梢褐,系架構(gòu)字段呢旺遮?不行的,因為這樣就冗余了盈咳,非主鍵外的字段形成了依賴關系(依賴到學生信息表了)耿眉!正確的做法是:學生表就只能增加一個系編號字段。
- 存儲過程與觸發(fā)器的區(qū)別
存儲過程和觸發(fā)器都是SQL語句集鱼响;觸發(fā)器不可用CALL調(diào)用跷敬,而是在用戶執(zhí)行某些語句后自動調(diào)用;
- 分表與分區(qū)
分表 :真正的分表热押,每張表對應三個文件西傀;提高MYSQL的并發(fā)能力;
分區(qū) :表中的數(shù)據(jù)分成多個區(qū)塊桶癣;突破磁盤的讀寫能力拥褂;
- 數(shù)據(jù)庫隔離級別
臟讀 | 一個事務讀取了另一個事務未提交的數(shù)據(jù) |
---|---|
不可重復讀 | 在一次事務范圍內(nèi),讀取同一數(shù)據(jù)產(chǎn)生了不同的值 |
虛讀 | 讀取整體的數(shù)據(jù)后牙寞,因其他事務對數(shù)據(jù)的更新饺鹃,再次查詢時結(jié)果不同 |
串行化 | 3種均可避免 |
---|---|
可重復讀(默認) | 避免1,2 |
讀已提交 | 1 |
讀未提交 | 無 |
- MYSQL的兩種存儲引擎
MYISAM | 不支持事務莫秆,不支持外鍵,表鎖悔详;插入數(shù)據(jù)時鎖定整個表镊屎,查行數(shù)時無需整表掃描 |
---|---|
INNODB | 支持事務,外鍵茄螃,行鎖缝驳,查表總行數(shù)時,全表掃描归苍; |
- MYSQL索引算法
HASH | 適合等值查找用狱,不適合范圍,不能排序 |
---|---|
BTREE | 適合范圍查找拼弃,無hash沖突 |
- 聚集索引和非聚集索引
聚集索引 | 數(shù)據(jù)按索引順序存儲夏伊,節(jié)點存儲的是真實數(shù)據(jù) |
---|---|
非聚集索引 | 節(jié)點存儲的是指向真正數(shù)據(jù)的指針 |
- 索引的優(yōu)缺點
優(yōu)點 | 提高查詢效率 |
---|---|
缺點 | 降低了更新效率 |
- 兩種存儲引擎索引的區(qū)別
Innodb | 主索引的數(shù)據(jù)文件本身就是索引文件;輔助索引記錄主鍵的值吻氧; |
---|---|
MyISAM | 主索引數(shù)據(jù)文件和索引文件分離溺忧;與主索引無區(qū)別; |
- 數(shù)據(jù)庫的主從復制
一個服務器作為主服務器盯孙,一個或多個服務器作為從服務器鲁森,主服務器將更新寫到二進制日志,當一個從服務器連接到主服務器時镀梭,通知主服務器讀取日志刀森,接收從那時起發(fā)生的所有更新踱启。解決:數(shù)據(jù)分布报账,負載平衡,備份埠偿,高可用性和容錯性
基于語句 | 在主服務器上執(zhí)行的語句透罢,在從服務器上也執(zhí)行 |
---|---|
基于行 | 將改變的內(nèi)容復制過去 |
混合類型 | 語句復制失敗時采用行的形式 |
- 數(shù)據(jù)庫連接池
為數(shù)據(jù)庫連接建立一個緩沖池,防止過于大量的連接的建立與管理冠蒋;
- 存儲過程
存儲過程是一些預編譯的SQL語句羽圃,執(zhí)行效率較高
- 樂觀鎖和悲觀鎖
樂觀鎖 | 假定不會發(fā)生并發(fā)沖突,只在提交時檢查抖剿,若有其他數(shù)據(jù)更新了數(shù)據(jù)朽寞,則回滾;使用數(shù)據(jù)版本標示數(shù)據(jù)(時間戳斩郎,版本號) |
---|---|
悲觀鎖 | 假定會發(fā)生并發(fā)沖突脑融,屏蔽一切破壞數(shù)據(jù)庫一致性的操作,主要用于數(shù)據(jù)爭用激烈的環(huán)境缩宜,以及鎖成本低于回滾成本時肘迎;排他鎖甥温; |
- 如何設計一個高并發(fā)的系統(tǒng)
① 數(shù)據(jù)庫的優(yōu)化,包括合理的事務隔離級別妓布、SQL語句優(yōu)化姻蚓、索引的優(yōu)化
② 使用緩存,盡量減少數(shù)據(jù)庫 IO
③ 分布式數(shù)據(jù)庫匣沼、分布式緩存
④ 服務器的負載均衡
- 什么情況下設置了索引但無法使用
① 以“%”開頭的LIKE語句狰挡,模糊匹配
② OR語句前后沒有同時使用索引
③ 數(shù)據(jù)類型出現(xiàn)隱式轉(zhuǎn)化(如varchar不加單引號的話可能會自動轉(zhuǎn)換為int型
- 實踐中如何優(yōu)化MySQL
① SQL語句及索引的優(yōu)化
② 數(shù)據(jù)庫表結(jié)構(gòu)的優(yōu)化
③ 系統(tǒng)配置的優(yōu)化
④ 硬件的優(yōu)化
-
優(yōu)化數(shù)據(jù)庫的方法
· 選取最適用的字段屬性,盡可能減少定義字段寬度肛著,盡量把字段設置NOTNULL圆兵,例如'省份'、'性別'最好適用ENUM
· 使用連接(JOIN)來代替子查詢
· 適用聯(lián)合(UNION)來代替手動創(chuàng)建的臨時表
· 事務處理
· 鎖定表枢贿、優(yōu)化事務處理
· 適用外鍵殉农,優(yōu)化鎖定表
· 建立索引
· 優(yōu)化查詢語句
-
簡單描述mysql中,索引局荚,主鍵超凳,唯一索引,聯(lián)合索引的區(qū)別耀态,對數(shù)據(jù)庫的性能有什么影響(從讀寫兩方面)
索引是一種特殊的文件(InnoDB數(shù)據(jù)表上的索引是表空間的一個組成部分)轮傍,它們包含著對數(shù)據(jù)表里所有記錄的引用指針。
普通索引(由關鍵字KEY或INDEX定義的索引)的唯一任務是加快對數(shù)據(jù)的訪問速度首装。
普通索引允許被索引的數(shù)據(jù)列包含重復的值创夜。如果能確定某個數(shù)據(jù)列將只包含彼此各不相同的值,在為這個數(shù)據(jù)列創(chuàng)建索引的時候就應該用關鍵字UNIQUE把它定義為一個唯一索引仙逻。也就是說驰吓,唯一索引可以保證數(shù)據(jù)記錄的唯一性。
主鍵系奉,是一種特殊的唯一索引檬贰,在一張表中只能定義一個主鍵索引,主鍵用于唯一標識一條記錄缺亮,使用關鍵字 PRIMARY KEY 來創(chuàng)建翁涤。
索引可以覆蓋多個數(shù)據(jù)列,如像INDEX(columnA, columnB)索引萌踱,這就是聯(lián)合索引葵礼。
索引可以極大的提高數(shù)據(jù)的查詢速度,但是會降低插入并鸵、刪除鸳粉、更新表的速度,因為在執(zhí)行這些寫操作時能真,還要操作索引文件赁严。
-
數(shù)據(jù)庫中的事務是什么?
事務(transaction)是作為一個單元的一組有序的數(shù)據(jù)庫操作扰柠。如果組中的所有操作都成功,則認為事務成功疼约,即使只有一個操作失敗卤档,事務也不成功。如果所有操作完成程剥,事務則提交劝枣,其修改將作用于所有其他數(shù)據(jù)庫進程。如果一個操作失敗织鲸,則事務將回滾舔腾,該事務所有操作的影響都將取消。ACID 四大特性,原子性搂擦、隔離性稳诚、一致性、持久性瀑踢。
-
對于關系型數(shù)據(jù)庫而言扳还,索引是相當重要的概念,請回答有關索引的幾個問題
a)橱夭、索引的目的是什么氨距?
快速訪問數(shù)據(jù)表中的特定信息,提高檢索速度
創(chuàng)建唯一性索引棘劣,保證數(shù)據(jù)庫表中每一行數(shù)據(jù)的唯一性俏让。
加速表和表之間的連接
使用分組和排序子句進行數(shù)據(jù)檢索時,可以顯著減少查詢中分組和排序的時間
b)茬暇、索引對數(shù)據(jù)庫系統(tǒng)的負面影響是什么首昔?
負面影響:
創(chuàng)建索引和維護索引需要耗費時間,這個時間隨著數(shù)據(jù)量的增加而增加而钞;索引需要占用物理空間沙廉,不光是表需要占用數(shù)據(jù)空間拘荡,每個索引也需要占用物理空間臼节;當對表進行增、刪珊皿、改网缝、的時候索引也要動態(tài)維護,這樣就降低了數(shù)據(jù)的維護速度蟋定。
c)粉臊、為數(shù)據(jù)表建立索引的原則有哪些?
在最頻繁使用的驶兜、用以縮小查詢范圍的字段上建立索引扼仲。
在頻繁使用的远寸、需要排序的字段上建立索引
d)、 什么情況下不宜建立索引屠凶?
對于查詢中很少涉及的列或者重復值比較多的列驰后,不宜建立索引。
對于一些特殊的數(shù)據(jù)類型矗愧,不宜建立索引灶芝,比如文本字段(text)等
-
簡述在MySQL數(shù)據(jù)庫中MyISAM和InnoDB的區(qū)別
區(qū)別于其他數(shù)據(jù)庫的最重要的特點就是其插件式的表存儲引擎。切記:存儲引擎是基于表的唉韭,而不是數(shù)據(jù)庫夜涕。
InnoDB與MyISAM的區(qū)別:
InnoDB存儲引擎: 主要面向OLTP(Online Transaction Processing,在線事務處理)方面的應用属愤,是第一個完整支持ACID事務的存儲引擎(BDB第一個支持事務的存儲引擎女器,已經(jīng)停止開發(fā))。
特點:
· 行鎖設計住诸、支持外鍵,支持事務晓避,支持并發(fā),鎖粒度是支持mvcc得行級鎖只壳;
MyISAM存儲引擎: 是MySQL官方提供的存儲引擎俏拱,主要面向OLAP(Online Analytical Processing,在線分析處理)方面的應用。
特點:
不支持事務吼句,鎖粒度是支持并發(fā)插入得表級鎖锅必,支持表所和全文索引。操作速度快惕艳,不能讀寫操作太頻繁搞隐;
-
解釋MySQL外連接、內(nèi)連接與自連接的區(qū)別
先說什么是交叉連接: 交叉連接又叫笛卡爾積远搪,它是指不使用任何條件劣纲,直接將一個表的所有記錄和另一個表中的所有記錄一一匹配。
內(nèi)連接 則是只有條件的交叉連接谁鳍,根據(jù)某個條件篩選出符合條件的記錄癞季,不符合條件的記錄不會出現(xiàn)在結(jié)果集中,即內(nèi)連接只連接匹配的行倘潜。
外連接 其結(jié)果集中不僅包含符合連接條件的行绷柒,而且還會包括左表、右表或兩個表中
的所有數(shù)據(jù)行涮因,這三種情況依次稱之為左外連接废睦,右外連接,和全外連接养泡。
左外連接嗜湃,也稱左連接奈应,左表為主表,左表中的所有記錄都會出現(xiàn)在結(jié)果集中购披,對于那些在右表中并沒有匹配的記錄钥组,仍然要顯示,右邊對應的那些字段值以NULL來填充今瀑。右外連接程梦,也稱右連接,右表為主表橘荠,右表中的所有記錄都會出現(xiàn)在結(jié)果集中屿附。左連接和右連接可以互換,MySQL目前還不支持全外連接哥童。
- 完整性約束包括哪些挺份?
答:數(shù)據(jù)完整性(Data Integrity)是指數(shù)據(jù)的精確(Accuracy)和可靠性(Reliability)。
分為以下四類:
實體完整性:規(guī)定表的每一行在表中是惟一的實體贮懈。
域完整性:是指表中的列必須滿足某種特定的數(shù)據(jù)類型約束匀泊,其中約束又包括取值范圍铺浇、精度等規(guī)定瘟檩。
參照完整性:是指兩個表的主關鍵字和外關鍵字的數(shù)據(jù)應一致,保證了表之間的數(shù)據(jù)的一致性她渴,防止了數(shù)據(jù)丟失或無意義的數(shù)據(jù)在數(shù)據(jù)庫中擴散抡医。
用戶定義的完整性:不同的關系數(shù)據(jù)庫系統(tǒng)根據(jù)其應用環(huán)境的不同躲因,往往還需要一些特殊的約束條件。用戶定義的完整性即是針對某個特定關系數(shù)據(jù)庫的約束條件忌傻,它反映某一具體應用必須滿足的語義要求大脉。
與表有關的約束:包括列約束(NOT NULL(非空約束))和表約束(PRIMARY KEY、foreign key水孩、check镰矿、UNIQUE) 。
- 什么是事務俘种?及其特性秤标?
答:事務:是一系列的數(shù)據(jù)庫操作,是數(shù)據(jù)庫應用的基本邏輯單位安疗。
事務特性:
(1)原子性:即不可分割性抛杨,事務要么全部被執(zhí)行够委,要么就全部不被執(zhí)行荐类。
(2)一致性或可串性。事務的執(zhí)行使得數(shù)據(jù)庫從一種正確狀態(tài)轉(zhuǎn)換成另一種正確狀態(tài)
(3)隔離性茁帽。在事務正確提交之前玉罐,不允許把該事務對數(shù)據(jù)的任何改變提供給任何其他事務屈嗤,
(4) 持久性。事務正確提交后吊输,其結(jié)果將永久保存在數(shù)據(jù)庫中饶号,即使在事務提交后有了其他故障,事務的處理結(jié)果也會得到保存季蚂。
或者這樣理解:
事務就是被綁定在一起作為一個邏輯工作單元的SQL語句分組茫船,如果任何一個語句操作失敗那么整個操作就被失敗,以后操作就會回滾到操作前狀態(tài)扭屁,或者是上有個節(jié)點算谈。為了確保要么執(zhí)行,要么不執(zhí)行料滥,就可以使用事務然眼。要將有組語句作為事務考慮,就需要通過ACID測試葵腹,即原子性高每,一致性,隔離性和持久性践宴。
- 什么叫視圖鲸匿?游標是什么?
答:視圖是一種虛擬的表阻肩,具有和物理表相同的功能晒骇。可以對視圖進行增磺浙,改洪囤,查,操作撕氧,視圖通常是有一個表或者多個表的行或列的子集瘤缩。對視圖的修改不影響基本表。它使得我們獲取數(shù)據(jù)更容易伦泥,相比多表查詢剥啤。
(1) 視圖能夠簡化用戶的操作 (2) 視圖使用戶能以多種角度看待同一數(shù)據(jù); (3) 視圖為數(shù)據(jù)庫提供了一定程度的邏輯獨立性不脯; (4) 視圖能夠?qū)C密數(shù)據(jù)提供安全保護府怯。
游標:是對查詢出來的結(jié)果集作為一個單元來有效的處理。游標可以定在該單元中的特定行防楷,從結(jié)果集的當前行檢索一行或多行牺丙。可以對結(jié)果集當前行做修改。一般不使用游標冲簿,但是需要逐條處理數(shù)據(jù)的時候粟判,游標顯得十分重要。
- 什么是存儲過程峦剔?用什么來調(diào)用档礁?
存儲過程是一個預編譯的SQL語句,優(yōu)點是允許模塊化的設計吝沫,就是說只需創(chuàng)建一次呻澜,以后在該程序中就可以調(diào)用多次。如果某次操作需要執(zhí)行多次SQL惨险,使用存儲過程比單純SQL語句執(zhí)行要快易迹。可以用一個命令對象來調(diào)用存儲過程平道。
- 主鍵睹欲、外鍵和索引的區(qū)別?
定義:
主鍵--唯一標識一條記錄一屋,不能有重復的窘疮,不允許為空
外鍵--表的外鍵是另一表的主鍵, 外鍵可以有重復的, 可以是空值
索引--該字段沒有重復值,但可以有一個空值
作用:
主鍵--用來保證數(shù)據(jù)完整性
外鍵--用來和其他表建立聯(lián)系用的
索引--是提高查詢排序的速度
個數(shù):
主鍵--主鍵只能有一個
外鍵--一個表可以有多個外鍵
索引--一個表可以有多個唯一索引
- 對SQL語句優(yōu)化有哪些方法
(1)Where子句中:where表之間的連接必須寫在其他Where條件之前冀墨,那些可以過濾掉最大數(shù)量記錄的條件必須寫在Where子句的末尾.HAVING最后闸衫。
(2)用EXISTS替代IN、用NOT EXISTS替代NOT IN诽嘉。
(3) 避免在索引列上使用計算
(4)避免在索引列上使用IS NULL和IS NOT NULL
(5)對查詢進行優(yōu)化蔚出,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引虫腋。
(6)應盡量避免在 where 子句中對字段進行 null 值判斷骄酗,否則將導致引擎放棄使用索引而進行全表掃描
(7)應盡量避免在 where 子句中對字段進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描
- SQL語句中‘相關子查詢’與‘非相關子查詢’有什么區(qū)別悦冀?
答:子查詢:嵌套在其他查詢中的查詢稱之趋翻。
子查詢又稱內(nèi)部,而包含子查詢的語句稱之外部查詢(又稱主查詢)盒蟆。
所有的子查詢可以分為兩類踏烙,即相關子查詢和非相關子查詢
(1)非相關子查詢是獨立于外部查詢的子查詢,子查詢總共執(zhí)行一次历等,執(zhí)行完畢后將值傳遞給外部查詢讨惩。
(2)相關子查詢的執(zhí)行依賴于外部查詢的數(shù)據(jù),外部查詢執(zhí)行一行寒屯,子查詢就執(zhí)行一次荐捻。
故非相關子查詢比相關子查詢效率高
- 如何進行SQL優(yōu)化?
(1)選擇正確的存儲引擎
以 MySQL為例,包括有兩個存儲引擎 MyISAM 和 InnoDB靴患,每個引擎都有利有弊仍侥。
MyISAM 適合于一些需要大量查詢的應用要出,但其對于有大量寫操作并不是很好鸳君。甚至你只是需要update一個字段,整個表都會被鎖起來患蹂,而別的進程或颊,就算是讀進程都無法操作直到讀操作完成。另外传于,MyISAM 對于 SELECT COUNT(*) 這類的計算是超快無比的囱挑。
InnoDB 的趨勢會是一個非常復雜的存儲引擎,對于一些小的應用沼溜,它會比 MyISAM 還慢平挑。但是它支持“行鎖” ,于是在寫操作比較多的時候系草,會更優(yōu)秀通熄。并且,他還支持更多的高級應用找都,比如:事務唇辨。
(2)優(yōu)化字段的數(shù)據(jù)類型
記住一個原則,越小的列會越快能耻。如果一個表只會有幾列罷了(比如說字典表赏枚,配置表),那么晓猛,我們就沒有理由使用 INT 來做主鍵饿幅,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 會更經(jīng)濟一些。如果你不需要記錄時間戒职,使用 DATE 要比 DATETIME 好得多诫睬。當然,你也需要留夠足夠的擴展空間帕涌。
(3)為搜索字段添加索引
索引并不一定就是給主鍵或是唯一的字段摄凡。如果在你的表中,有某個字段你總要會經(jīng)常用來做搜索蚓曼,那么最好是為其建立索引亲澡,除非你要搜索的字段是大的文本字段,那應該建立全文索引纫版。
(4)避免使用Select 從數(shù)據(jù)庫里讀出越多的數(shù)據(jù)床绪,那么查詢就會變得越慢。并且,如果你的數(shù)據(jù)庫服務器和WEB服務器是兩臺獨立的服務器的話癞己,這還會增加網(wǎng)絡傳輸?shù)呢撦d膀斋。即使你要查詢數(shù)據(jù)表的所有字段,也盡量不要用通配符痹雅,善用內(nèi)置提供的字段排除定義也許能給帶來更多的便利仰担。
(5)使用 ENUM 而不是 VARCHAR
ENUM 類型是非常快和緊湊的绩社。在實際上摔蓝,其保存的是 TINYINT,但其外表上顯示為字符串愉耙。這樣一來贮尉,用這個字段來做一些選項列表變得相當?shù)耐昝馈@缙友兀詣e猜谚、民族、部門和狀態(tài)之類的這些字段的取值是有限而且固定的赌渣,那么魏铅,你應該使用 ENUM 而不是 VARCHAR。
(6)盡可能的使用 NOT NULL
除非你有一個很特別的原因去使用 NULL 值锡垄,你應該總是讓你的字段保持 NOT NULL沦零。 NULL其實需要額外的空間,并且货岭,在你進行比較的時候路操,你的程序會更復雜。 當然千贯,這里并不是說你就不能使用NULL了屯仗,現(xiàn)實情況是很復雜的,依然會有些情況下搔谴,你需要使用NULL值魁袜。
(7)固定長度的表會更快
如果表中的所有字段都是“固定長度”的,整個表會被認為是 “static” 或 “fixed-length”敦第。 例如峰弹,表中沒有如下類型的字段: VARCHAR,TEXT芜果,BLOB鞠呈。只要你包括了其中一個這些字段,那么這個表就不是“固定長度靜態(tài)表”了右钾,這樣蚁吝,MySQL 引擎會用另一種方法來處理旱爆。
固定長度的表會提高性能,因為MySQL搜尋得會更快一些窘茁,因為這些固定的長度是很容易計算下一個數(shù)據(jù)的偏移量的怀伦,所以讀取的自然也會很快。而如果字段不是定長的山林,那么房待,每一次要找下一條的話,需要程序找到主鍵捌朴。
并且吴攒,固定長度的表也更容易被緩存和重建张抄。不過砂蔽,唯一的副作用是,固定長度的字段會浪費一些空間署惯,因為定長的字段無論你用不用左驾,他都是要分配那么多的空間。
- 大表優(yōu)化
字段
- 盡量使用
TINYINT
极谊、SMALLINT
诡右、MEDIUM_INT
作為整數(shù)類型而非INT
,如果非負則加上UNSIGNED
-
VARCHAR
的長度只分配真正需要的空間 - 使用枚舉或整數(shù)代替字符串類型
- 盡量使用
TIMESTAMP
而非DATETIME
轻猖, - 單表不要有太多字段帆吻,建議在20以內(nèi)
- 避免使用NULL字段,很難查詢優(yōu)化且占用額外索引空間
- 用整型來存IP
索引
- 索引并不是越多越好咙边,要根據(jù)查詢有針對性的創(chuàng)建猜煮,考慮在
WHERE
和ORDER BY
命令上涉及的列建立索引,可根據(jù)EXPLAIN
來查看是否用了索引還是全表掃描 - 應盡量避免在
WHERE
子句中對字段進行NULL
值判斷败许,否則將導致引擎放棄使用索引而進行全表掃描 - 值分布很稀少的字段不適合建索引王带,例如"性別"這種只有兩三個值的字段
- 字符字段只建前綴索引
- 字符字段最好不要做主鍵
- 不用外鍵,由程序保證約束
- 盡量不用
UNIQUE
市殷,由程序保證約束 - 使用多列索引時主意順序和查詢條件保持一致愕撰,同時刪除不必要的單列索引
查詢SQL
- 可通過開啟慢查詢?nèi)罩緛碚页鲚^慢的SQL
- 不做列運算:
SELECT id WHERE age + 1 = 10
,任何對列的操作都將導致表掃描醋寝,它包括數(shù)據(jù)庫教程函數(shù)搞挣、計算表達式等等,查詢時要盡可能將操作移至等號右邊 - sql語句盡可能簡單:一條sql只能在一個cpu運算音羞;大語句拆小語句囱桨,減少鎖時間;一條大sql可以堵死整個庫
- 不用
SELECT *
-
OR
改寫成IN
:OR
的效率是n級別黄选,IN
的效率是log(n)級別蝇摸,in的個數(shù)建議控制在200以內(nèi) - 不用函數(shù)和觸發(fā)器婶肩,在應用程序?qū)崿F(xiàn)
- 避免
%xxx
式查詢 - 少用
JOIN
- 使用同類型進行比較,比如用
'123'
和'123'
比貌夕,123
和123
比 - 盡量避免在
WHERE
子句中使用!=或<>操作符律歼,否則將引擎放棄使用索引而進行全表掃描 - 對于連續(xù)數(shù)值,使用
BETWEEN
不用IN
:SELECT id FROM t WHERE num BETWEEN 1 AND 5
- 列表數(shù)據(jù)不要拿全表啡专,要使用
LIMIT
來分頁险毁,每頁數(shù)量也不要太大
引擎
目前廣泛使用的是MyISAM和InnoDB兩種引擎:
MyISAM
MyISAM引擎是MySQL 5.1及之前版本的默認引擎,它的特點是:
- 不支持行鎖们童,讀取時對需要讀到的所有表加鎖畔况,寫入時則對表加排它鎖
- 不支持事務
- 不支持外鍵
- 不支持崩潰后的安全恢復
- 在表有讀取查詢的同時,支持往表中插入新紀錄
- 支持
BLOB
和TEXT
的前500個字符索引慧库,支持全文索引 - 支持延遲更新索引跷跪,極大提升寫入性能
- 對于不會進行修改的表,支持壓縮表齐板,極大減少磁盤空間占用
InnoDB
InnoDB在MySQL 5.5后成為默認索引吵瞻,它的特點是:
- 支持行鎖,采用MVCC來支持高并發(fā)
- 支持事務
- 支持外鍵
- 支持崩潰后的安全恢復
- 不支持全文索引
總體來講甘磨,MyISAM適合SELECT
密集型的表橡羞,而InnoDB適合INSERT
和UPDATE
密集型的表
緩存
緩存可以發(fā)生在這些層次:
- MySQL內(nèi)部:在系統(tǒng)調(diào)優(yōu)參數(shù)介紹了相關設置
- 數(shù)據(jù)訪問層:比如MyBatis針對SQL語句做緩存,而Hibernate可以精確到單個記錄济舆,這里緩存的對象主要是持久化對象
Persistence Object
- 應用服務層:這里可以通過編程手段對緩存做到更精準的控制和更多的實現(xiàn)策略卿泽,這里緩存的對象是數(shù)據(jù)傳輸對象
Data Transfer Object
- Web層:針對web頁面做緩存
- 瀏覽器客戶端:用戶端的緩存
可以根據(jù)實際情況在一個層次或多個層次結(jié)合加入緩存。這里重點介紹下服務層的緩存實現(xiàn)滋觉,目前主要有兩種方式:
- 直寫式(Write Through):在數(shù)據(jù)寫入數(shù)據(jù)庫后签夭,同時更新緩存,維持數(shù)據(jù)庫與緩存的一致性椎瘟。這也是當前大多數(shù)應用緩存框架如Spring Cache的工作方式覆致。這種實現(xiàn)非常簡單,同步好肺蔚,但效率一般煌妈。
- 回寫式(Write Back):當有數(shù)據(jù)要寫入數(shù)據(jù)庫時,只會更新緩存宣羊,然后異步批量的將緩存數(shù)據(jù)同步到數(shù)據(jù)庫上璧诵。這種實現(xiàn)比較復雜,需要較多的應用邏輯仇冯,同時可能會產(chǎn)生數(shù)據(jù)庫與緩存的不同步之宿,但效率非常高。
- Mysql鎖機制
粒度:表級鎖和行級鎖
分類:
- 共享鎖:共享鎖(S鎖)又稱為讀鎖苛坚,若事務T對數(shù)據(jù)對象A加上S鎖比被,則事務T只能讀A色难;其他事務只能再對A加S鎖,而不能加X鎖等缀,直到T釋放A上的S鎖枷莉。這就保證了其他事務可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改尺迂。
- 派他鎖:若事務T對數(shù)據(jù)對象A加上X鎖笤妙,則只允許T讀取和修改A,其它任何事務都不能再對A加任何類型的鎖噪裕,直到T釋放A上的鎖蹲盘。它防止任何其它事務獲取資源上的鎖,直到在事務的末尾將資源上的原始鎖釋放為止膳音。在更新操作(INSERT召衔、UPDATE 或 DELETE)過程中始終應用排它鎖。
- 什么是存儲過程严蓖?
存儲過程就像我們編程語言中的函數(shù)一樣薄嫡,封裝了我們的代碼(PLSQL氧急、T-SQL)颗胡。
存儲過程的優(yōu)點:
- 能夠?qū)⒋a封裝起來
- 保存在數(shù)據(jù)庫之中
- 讓編程語言進行調(diào)用
- 存儲過程是一個預編譯的代碼塊,執(zhí)行效率比較高
- 一個存儲過程替代大量T_SQL語句 吩坝,可以降低網(wǎng)絡通信量毒姨,提高通信速率
存儲過程的缺點:
- 每個數(shù)據(jù)庫的存儲過程語法幾乎都不一樣,十分難以維護(不通用)
- 業(yè)務邏輯放在數(shù)據(jù)庫上钉寝,難以迭代
- 什么是視圖弧呐?
(1)視圖是一種虛表
(2)視圖建立在已有表的基礎上, 視圖賴以建立的這些表稱為基表
(3)向視圖提供數(shù)據(jù)內(nèi)容的語句為 SELECT 語句,可以將視圖理解為存儲起來的 SELECT 語句
(4)視圖向用戶提供基表數(shù)據(jù)的另一種表現(xiàn)形式
(5)視圖沒有存儲真正的數(shù)據(jù),真正的數(shù)據(jù)還是存儲在基表中
(6)程序員雖然操作的是視圖嵌纲,但最終視圖還會轉(zhuǎn)成操作基表
(7)一個基表可以有0個或多個視圖