l 第一範式(1NF):強調的是列的原子性,即列不可以再分紅其餘幾列。mysql
如電話列可進行拆分---家庭電話、公司電話算法
l 第二範式(2NF):首先是 1NF,另外包含兩部份內容,一是表必須有主鍵;二是沒有包含在主鍵中的列必須徹底依賴於主鍵,而不能只依賴於主鍵的一部分。sql
l 第三範式(3NF):首先是 2NF,另外非主鍵列必須直接依賴於主鍵,不能存在傳遞依賴。數據庫
好比Student表(學號,姓名,年齡,性別,所在院校,院校地址,院校電話)緩存
這樣一個表結構,就存在上述關係。 學號--> 所在院校 --> (院校地址,院校電話)併發
這樣的表結構,咱們應該拆開來,以下。app
(學號,姓名,年齡,性別,所在院校)--(所在院校,院校地址,院校電話)函數
知足這些規範的數據庫是簡潔的、結構明晰的;同時,不會發生插入(insert)、刪除(delete)和更新(update)操做異常。性能
l 數字類型優化
Float和double選擇(儘可能選擇float)
區分開TINYINT / INT / BIGINT,能肯定不會使用負數的字段,建議添加 unsigned定義
可以用數字類型的字段儘可能選擇數字類型而不用字符串類型的
l 字符類型
char,varchar,TEXT的選擇:非萬不得已不要使用 TEXT 數據類型,定長字段,建議使用 CHAR 類型(填空格),不定長字段儘可能使用 VARCHAR(自動適應長度,超過階段),且僅僅設定適當的最大長度
l 時間類型
按選擇優先級排序DATE(精確到天)、TIMESTAMP、DATETIME(精確到時間)
l ENUM
對於狀態字段,能夠嘗試使用 ENUM 來存放
l 避免使用NULL字段,很難查詢優化且佔用額外索引空間
一樣的內容使用不一樣字符集表示所佔用的空間大小會有較大的差別,因此經過使用合適的字符集,能夠幫助咱們儘量減小數據量,進而減小IO操做次數。
1.純拉丁字符能表示的內容,選擇 latin1 字符編碼
2.中文可選用utf-8
3.MySQL的數據類型能夠精確到字段,因此當咱們須要大型數據庫中存放多字節數據的時候,能夠經過對不一樣表不一樣字段使用不一樣的數據類型來較大程度減少數據存儲量,進而下降 IO 操做次數並提升緩存命中率
1) 只返回須要的數據
a) 不要寫SELECT *的語句
b) 合理寫WHERE子句,不要寫沒有WHERE的SQL語句。
2) 儘可能少作重複的工做
能夠合併一些sql語句
3) 適當創建索引(不是越多越好)但如下幾點會進行全表掃描
a) 左模糊查詢’%...’
b) 使用了不等操做符!=
c) Or使用不當,or兩邊都必須有索引才行
d) In 、not in
e) Where子句對字段進行表達式操做
f) 對於建立的複合索引(從最左邊開始組合),查詢條件用到的列必須從左邊開始不能間隔。不然無效,複合索引的結構與電話簿相似
g) 全文索引:當於對文件創建了一個以詞庫爲目錄的索引(文件大全文索引比模糊匹配效果好)
能在char、varchar、text類型的列上面建立全文索引
MySQL 5.6 Innodb引擎也能進行全文索引
搜索語法:MATCH (列名1, 列名2,…) AGAINST (搜索字符串 [搜索修飾符])
若是列類型是字符串,但在查詢時把一個數值型常量賦值給了一個字符型的列名name,那麼雖然在name列上有索引,可是也沒有用到。
4) 使用join代替子查詢
5) 使用union代替手動建立臨時表
1、 建立索引,如下狀況不適合創建索引
l 表記錄太少
l 常常插入、刪除、修改的表
l 數據重複且分佈平均的表字段
2、 複合索引
若是一個表中的數據在查詢時有多個字段老是同時出現則這些字段就能夠做爲複合索引
索引是對數據庫表中一列或多列的值進行排序的一種結構。
優勢:
l 大大加快數據的檢索速度
l 建立惟一性索引,保證數據庫表中每一行數據的惟一性
l 能夠加速表和表之間的鏈接
缺點:
l 索引須要佔物理空間。
l 當對錶中的數據進行增長、刪除和修改的時候,索引也要動態的維護,
下降了數據的維護速度。
索引分類:
l 普通索引
create index zjj_temp_index_1 on zjj_temp_1(first_name);
drop index zjj_temp_index_1;
l 惟一索引,索引列的值必須惟一,但容許有空值
create unique index zjj_temp_1 on zjj_temp_1(id);
l 主鍵索引,它是一種特殊的惟一索引,不容許有空值。
l 組合索引
數據庫事務(Database Transaction) ,是指做爲單個邏輯工做單元執行的一系列操做,要麼徹底地執行,要麼徹底地不執行。
(1)原子性
事務必須是原子工做單元;對於其數據修改,要麼全都執行,要麼全都不執行。
(2)一致性
事務的一致性指的是在一個事務執行以前和執行以後數據庫都必須處於一致性狀態。事務執行的結果必須是使數據庫從一個一致性狀態變到另外一個一致性狀態。
(3) 隔離性(關於事務的隔離性數據庫提供了多種隔離級別)
一個事務的執行不能干擾其它事務。即一個事務內部的操做及使用的數據對其它併發事務是隔離的,併發執行的各個事務之間不能互相干擾。
(4)持久性
事務完成以後,它對於數據庫中的數據改變是永久性的。該修改即便出現系統故障也將一
直保持。
在介紹數據庫提供的各類隔離級別以前,咱們先看看若是不考慮事務的隔離性,會發生的幾種問題:
l 髒讀
髒讀是指在一個事務處理過程裏讀取了另外一個未提交的事務中的數據。
l 不可重複讀
l 幻讀
幻讀和不可重複讀都是讀取了另外一條已經提交的事務,不可重複讀重點在於update和delete,而幻讀的重點在於insert。
在可重複讀中,該sql第一次讀取到數據後,就將這些數據加鎖,其它事務沒法修改這些數據,就能夠實現可重複 讀了。但這種方法卻沒法鎖住insert的數據,因此當事務A先前讀取了數據,或者修改了所有數據,事務B仍是能夠insert數據提交,這時事務A就會 發現莫名其妙多了一條以前沒有的數據,這就是幻讀,不能經過行鎖來避免。須要Serializable隔離級別 ,讀用讀鎖,寫用寫鎖,讀鎖和寫鎖互斥,這麼作能夠有效的避免幻讀、不可重複讀、髒讀等問題,但會極大的下降數據庫的併發能力。
如今來看看MySQL數據庫爲咱們提供的四種隔離級別:
① Serializable (串行化):可避免髒讀、不可重複讀、幻讀的發生。
② Repeatable read (可重複讀):可避免髒讀、不可重複讀的發生。
③ Read committed (讀已提交):可避免髒讀的發生。
④ Read uncommitted (讀未提交):最低級別,任何狀況都沒法保證。
在MySQL數據庫中默認的隔離級別爲Repeatable read (可重複讀)。
鎖模式包括:
l 共享鎖:(讀取)操做建立的鎖。其餘用戶能夠併發讀取數據,但任何事物都不能獲取數據上的排它鎖,直到已釋放全部共享鎖。
l 排他鎖(X鎖):對數據A加上排他鎖後,則其餘事務不能再對A加任任何類型的封鎖。獲准排他鎖的事務既能讀數據,又能修改數據。
l 更新鎖:
更新 (U) 鎖能夠防止一般形式的死鎖。若是兩個事務得到了資源上的共享模式鎖,而後試圖同時更新數據,則兩個事務需都要轉換共享鎖爲排它 (X) 鎖,而且每一個事務都等待另外一個事務釋放共享模式鎖,所以發生死鎖。
若要避免這種潛 在的死鎖問題,請使用更新 (U) 鎖。一次只有一個事務能夠得到資源的更新 (U) 鎖。若是事務修改資源,則更新 (U) 鎖轉換爲排它 (X) 鎖。不然,鎖轉換爲共享鎖。
鎖的粒度主要有如下幾種類型:
l 行鎖: 粒度最小,併發性最高
l 頁鎖:一次鎖定一頁。25個行鎖可升級爲一個頁鎖。
l 表鎖:粒度大,併發性低
l 數據庫鎖:控制整個數據庫操做
樂觀鎖:相對悲觀鎖而言,樂觀鎖假設認爲數據通常狀況下不會形成衝突,因此在數據進行提交更新的時候,纔會正式對數據的衝突與否進行檢測,若是發現衝突了,則讓返回用戶錯誤的信息,讓用戶決定如何去作。通常的實現樂觀鎖的方式就是記錄數據版本。
悲觀鎖:顧名思義,就是很悲觀,每次去拿數據的時候都認爲別人會修改,因此每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會block直到它拿到鎖。傳統的關係型數據庫裏邊就用到了不少這種鎖機制,好比行鎖,表鎖等,讀鎖,寫鎖等,都是在作操做以前先上鎖。
MyISAM、InnoDB區別
l MyISAM類型不支持事務處理等高級處理,而InnoDB類型支持。
l MyISAM表不支持外鍵,InnoDB支持
l MyISAM鎖的粒度是表級,而InnoDB支持行級鎖定。
l MyISAM支持全文類型索引,而InnoDB不支持全文索引。(mysql 5.6後innodb支持全文索引)
MyISAM相對簡單,因此在效率上要優於InnoDB,小型應用能夠考慮使用MyISAM。當你的數據庫有大量的寫入、更新操做而查詢比較少或者數據完整性要求比較高的時
候就選擇innodb表。當你的數據庫主要以查詢爲主,相比較而言更新和寫 入比較少,而且業務方面數據完整性要求不那麼嚴格,就選擇mysiam表。
MyISAM索引實現
MyISAM索引文件和數據文件是分離的,索引文件僅保存數據記錄的地址。
l 主索引
MyISAM引擎使用B+Tree做爲索引結構,葉節點的data域存放的是數據記錄的地址。
l 輔助索引
在MyISAM中,主索引和輔助索引(Secondary key)在結構上沒有任何區別,只是主索引要求key是惟一的,而輔助索引的key能夠重複。
MyISAM中索引檢索的算法爲首先按照B+Tree搜索算法搜索索引,若是指定的Key存在,則取出其data域的值,而後以data域的值爲地址,讀取相應數據記錄。
MyISAM的索引方式也叫作「非彙集」的,之因此這麼稱呼是爲了與InnoDB的彙集索引區分。
然InnoDB也使用B+Tree做爲索引結構,但具體實現方式卻與MyISAM大相徑庭.
l 主索引
InnoDB表數據文件自己就是主索引。
InnoDB主索引(同時也是數據文件)的示意圖,能夠看到葉節點包含了完整的數據記錄。這種索引叫作彙集索引。由於InnoDB的數據文件自己要按主鍵彙集,因此InnoDB要求表必須有主鍵(MyISAM能夠沒有),若是沒有顯式指定,則MySQL系統會自動選擇一個能夠惟一標識數據記錄的列做爲主鍵,若是不存在這種列,則MySQL自動爲InnoDB表生成一個隱含字段做爲主鍵,這個字段長度爲6個字節,類型爲長整形。
l 輔助索引
InnoDB的全部輔助索引都引用主鍵做爲data域。
彙集索引這種實現方式使得按主鍵的搜索十分高效,可是輔助索引搜索須要檢索兩遍索引:首先檢索輔助索引得到主鍵,而後用主鍵到主索引中檢索得到記錄。
不一樣存儲引擎的索引實現方式對於正確使用和優化索引都很是有幫助,例如知道了InnoDB的索引實現後,就很容易明白
一、爲何不建議使用過長的字段做爲主鍵,由於全部輔助索引都引用主索引,過長的主索引會令輔助索引變得過大。再例如,
二、用非單調的字段做爲主鍵在InnoDB中不是個好主意,由於InnoDB數據文件自己是一顆B+Tree,非單調的主鍵會形成在插入新記錄時數據文件爲了維持B+Tree的特性而頻繁的分裂調整,十分低效,而使用自增字段做爲主鍵則是一個很好的選擇。
InnoDB索引和MyISAM索引的區別:
l 一是主索引的區別,InnoDB的數據文件自己就是索引文件。而MyISAM的索引和數據是分開的。
l 二是輔助索引的區別:InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。而MyISAM的輔助索引和主索引沒有多大區別。
二叉查找樹(BST):
二叉排序樹或者是一棵空樹,或者是具備下列性質的二叉樹:
l 若左子樹不空,則左子樹上全部結點的值均小於它的根結點的值。
l 若右子樹不空,則右子樹上全部結點的值均大於它的根結點的值。
l 左、右子樹也分別爲二叉排序樹。
l 沒有鍵值相等的節點(所以,插入的時候必定是葉子節點)。
刪除算法
l 要刪除節點是葉子節點。
l 要刪除的節點只有一個孩子(左孩子或右孩子),這種狀況比較簡單,只須要將該孩子鏈接到當前節點的父節點便可。
l 要刪除的節點有兩個孩子,這個時候的算法就比較複雜(相比較於只有一個孩子的狀況)。首先咱們須要找到待刪除節點的左子樹上的最大值節點,或者右子樹上的最小值節點,而後將該節點的參數值與待刪除的節點參數值進行交換,最後刪除該節點,這樣須要刪除的參數就從該二叉樹中刪除了。
紅黑樹(Red Black Tree) 是一種自平衡二叉查找樹 :
l 每一個節點或者是黑色,或者是紅色。
l 根節點是黑色。
l 每一個葉子節點是黑色。
l 若是一個節點是紅色的,則它的子節點必須是黑色的。
l 從一個節點到該節點的子孫節點的全部路徑上包含相同數目的黑節點。
紅黑樹的各類操做的時間複雜度是O(log2N)。
紅黑樹 vs AVL
紅黑樹的查詢性能略微遜色於AVL樹,由於他比avl樹會稍微不平衡最多一層,也就是說紅黑樹的查詢性能只比相同內容的avl樹最多多一次比較,可是,紅黑樹在插入和刪除上完爆avl樹,avl樹每次插入刪除會進行大量的平衡度計算,而紅黑樹爲了維持紅黑性質所作的紅黑變換和旋轉的開銷,相較於avl樹爲了維持平衡的開銷要小得多
插入操做
紅父
若是新節點的父結點爲紅色,這時就須要進行一系列操做以保證整棵樹紅黑性質。以下圖所示,因爲父結點爲紅色,此時能夠斷定,祖父結點一定爲黑色。這時須要根據叔父結點的顏色來決定作什麼樣的操做。青色結點表示顏色未知。因爲有可能須要根結點到新點的路徑上進行屢次旋轉操做,而每次進行不平衡判斷的起始點(咱們可將其視爲新點)都不同。因此咱們在此使用一個藍色箭頭指向這個起始點,並稱之爲斷定點。
l 紅叔
當叔父結點爲紅色時,以下圖所示,無需進行旋轉操做,只要將父和叔結點變爲黑色,將祖父結點變爲紅色便可。但因爲祖父結點的父結點有可能爲紅色,從而違反紅黑樹性質。此時必須將祖父結點做爲新的斷定點繼續向上(迭代)進行平衡操做。
須要注意的是,不管「父節點」在「叔節點」的左邊仍是右邊,不管「新節點」是「父節點」的左孩子仍是右孩子,它們的操做都是徹底同樣的(其實這種狀況包括4種,只需調整顏色,不須要旋轉樹形)。
l 黑叔
當叔父結點爲黑色時,須要進行旋轉,如下圖示了全部的旋轉可能:
Case 1:
Case 2:
Case 3:
Case 4:
B-tree樹即B樹,B即Balanced,平衡的意思。由於B樹的原英文名稱爲B-tree,而國內不少人喜歡把B-tree譯做B-樹,其實,這是個很是很差的直譯,很容易讓人產生誤解。如人們可能會覺得B-樹是一種樹,而B樹又是另外一種樹。而事實上是,B-tree就是指的B樹。
m階B樹是一棵平衡的m路搜索樹。它是空樹,或者是知足下列性質的樹:
l 根結點的兒子數爲[2, M];
l 除根結點之外的非葉子結點的兒子數爲[M/2, M]; (M/2向上取整)
l 每一個結點存放至少M/2-1(取上整)和至多M-1個關鍵字;
l 非葉子結點的關鍵字個數=指向兒子的指針個數-1;
l 非葉子結點的關鍵字:K[1], K[2], …, K[X-1];且K[i] < K[i+1];
l 非葉子結點的指針:P[1], P[2], …, P[X];其中P[1]指向關鍵字小於K[1]的
子樹,P[X]指向關鍵字大於K[X-1]的子樹,其它P[i]指向關鍵字屬於(K[i-1], K[i])的子樹;
l 全部葉子結點位於同一層;
B+樹是B-樹的變體,也是一種多路搜索樹:
其定義基本與B-樹同,除了:
l 非葉子結點的子樹指針與關鍵字個數相同;
l 非葉子結點的子樹指針P[i],指向關鍵字值屬於[K[i], K[i+1])的子樹
(B-樹是開區間);
l 爲全部葉子結點增長一個指針鏈;
l 全部關鍵字都在葉子結點出現;
l SELECT * FROM table ORDER BY field DESC; (ASC|DESC)
SELECT DISTINCT field from table where 範圍
l INSERT INTO table_name (column1,column2,column3,...)
VALUES (value1,value2,value3,...);
l UPDATE table_name SET column1=value1,column2=value2,...
WHERE some_column=some_value;
l DELETE FROM table_name WHERE some_column=some_value;
LIKE 操做符
SELECT column_name(s) FROM table_name WHERE column_name LIKE pattern;
IN 操做符
SELECT column_name(s) FROM table_name WHERE column_name
IN (value1,value2,...);
BETWEEN 操做符
SELECT column_name(s) FROM table_name WHERE column_name BETWEEN
JOIN
左鏈接,右鏈接,內鏈接
left join(左聯接): 返回包括左表中的全部記錄和右表中聯結字段相等的記錄。
right join(右聯接): 返回包括右表中的全部記錄和左表中聯結字段相等的記錄。
inner join(等值鏈接): 只返回兩個表中聯結字段相等的行。(默認)
UNION 操做符
UNION 操做符用於合併兩個或多個 SELECT 語句的結果集。
SELECT country, name FROM Websites WHERE country='CN'
UNION
SELECT country, app_name FROM apps WHERE country='CN'
ORDER BY country;
建立視圖
CREATE VIEW view_name AS SELECT column_name(s) FROM table_name WHERE condition
Avg() Count() Max() Min() Sum()
Group By():
GROUP BY 語句用於結合聚合函數,根據一個或多個列對結果集進行分組。
SELECT column_name, aggregate_function(column_name)
FROM table_name WHERE column_name operator value
GROUP BY column_name;
HAVING 子句可讓咱們篩選分組後的各組數據。
SELECT column_name, aggregate_function(column_name)
FROM table_name WHERE column_name operator value
GROUP BY column_name
HAVING aggregate_function(column_name) operator value;
如何查詢數據庫表結構,主鍵
desc tabl_name;
建表
CREATE TABLE 表名稱
(
列名稱1 數據類型,
....
)