一、什么是MYSQL
Mysql是最流行的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),在WEB應(yīng)用方面MySQL是最好的RDBMS(Relational Database Management System:關(guān)系數(shù)據(jù)庫管理系統(tǒng))應(yīng)用軟件之一。
關(guān)系型數(shù)據(jù)庫(RDBMS),是和非關(guān)系型數(shù)據(jù)庫并行的概念,后者不在本文討論范疇。而關(guān)系型數(shù)據(jù)庫就是由二維表(數(shù)據(jù)表)及其之間的聯(lián)系所組成的一個數(shù)據(jù)組織。
二、RDBMS 術(shù)語
在我們開始學(xué)習(xí)MySQL 數(shù)據(jù)庫前,讓我們先了解下RDBMS的一些術(shù)語:
數(shù)據(jù)庫:數(shù)據(jù)庫是一些關(guān)聯(lián)表的集合。.
數(shù)據(jù)表:表是數(shù)據(jù)的矩陣。在一個數(shù)據(jù)庫中的表看起來像一個簡單的電子表格。
列:一列(數(shù)據(jù)元素) 包含了相同的數(shù)據(jù), 例如郵政編碼的數(shù)據(jù)。
行:一行(=元組,或記錄)是一組相關(guān)的數(shù)據(jù),例如一條用戶訂閱的數(shù)據(jù)。
冗余:存儲兩倍數(shù)據(jù),冗余降低了性能,但提高了數(shù)據(jù)的安全性。
主鍵:主鍵是唯一的。一個數(shù)據(jù)表中只能包含一個主鍵。你可以使用主鍵來查詢數(shù)據(jù)。
外鍵:外鍵用于關(guān)聯(lián)兩個表。
復(fù)合鍵:復(fù)合鍵(組合鍵)將多個列作為一個索引鍵,一般用于復(fù)合索引。
索引:使用索引可快速訪問數(shù)據(jù)庫表中的特定信息。索引是對數(shù)據(jù)庫表中一列或多列的值進行排序的一種結(jié)構(gòu)。類似于書籍的目錄。
參照完整性:參照的完整性要求關(guān)系中不允許引用不存在的實體。與實體完整性是關(guān)系模型必須滿足的完整性約束條件,目的是保證數(shù)據(jù)的一致性。
三、數(shù)據(jù)庫設(shè)計范式
我們可以簡單地把數(shù)據(jù)庫理解為數(shù)據(jù)按照特定規(guī)范存儲在一起的集合。正如現(xiàn)實生活中倉庫管理員要根據(jù)貨物的性質(zhì)(易碎、怕潮、進出貨是否頻繁)等來設(shè)計倉庫布局,數(shù)據(jù)庫設(shè)計也要考慮減少數(shù)據(jù)冗余和提高查詢效率。通常人們在設(shè)計數(shù)據(jù)庫需要遵照下列三個范式:
1、無重復(fù)的列
數(shù)據(jù)庫表的每一列都是不可分割的原子數(shù)據(jù)項,而不能是集合,數(shù)組,記錄等非原子數(shù)據(jù)項。如果實體中的某個屬性有多個值時,必須拆分為不同的屬性。
比如:
|username | height | grade |三個字段,但字段grade下又分為math_grade,chinese_grade,則不符合要求,因為grade必須是不可再分的。滿足第一范式的數(shù)據(jù)庫則為關(guān)系型數(shù)據(jù)庫。
2、屬性完全依賴于主鍵
當(dāng)存在多個主鍵的時候,才會發(fā)生不符合第二范式的情況。比如有兩個主鍵,不能存在這樣的屬性,它只依賴于其中一個主鍵,這就是不符合第二范式。如果存在不符合第二范式的情況,那么這個屬性和主關(guān)鍵字的這一部分應(yīng)該分離出來形成一個新的實體,新實體與原實體之間是一對多的關(guān)系。
比如:|username | height | age | weather|,其中weather是不依賴于主鍵username的,所以不滿足第二范式。
又如:|studentname | teachername | studentage | teacherage|,其中studentage又studentname決定,teacherage由teachername 決定,存在多個主鍵,但其他字段不是由所有主鍵決定的,只是由其中一個主鍵決定的,所以不滿足第二范式。
3、屬性不能傳遞依賴于主屬性(屬性不依賴于其它非主鍵屬性)
比如:|studentname | school | school_address | school_tel|,其中school_address 、school_tel不是由學(xué)生直接決定的,而是由studentname到school再到school_address 、school_tel間接決定。
此外還有BC范式等,但在實際設(shè)計數(shù)據(jù)庫的過程中只需要滿足三大范式即可,因為范式是把雙刃劍,有利也有弊。
范式的目標(biāo)是消除數(shù)據(jù)冗余、減少操作異常(更新異常、插入異常、刪除異常)和讓數(shù)據(jù)結(jié)構(gòu)趨于合理,但范式越多,需要建立的數(shù)據(jù)表也越多,查詢時需要連接的表也增多,直接導(dǎo)致查詢復(fù)雜度(查詢語句變長)和查詢時間升高。
四、MYSQL常用語句
基本操作如創(chuàng)建與銷毀,單表的增刪改查(SELECT,DELETE,UPDATE,SELECT)在此不贅述,在這里記下可能忘記的操作。
1、like語句:
WHERE 子句中可以使用等號 (=) 來設(shè)定獲取數(shù)據(jù)的條件,如 "runoob_author = 'Sanjay'"。
但是有時候我們需要獲取 runoob_author 字段含有 "jay" 字符的所有記錄,這時我們就需要在 WHERE 子句中使用 SQL LIKE 子句。
SQL LIKE 子句中使用百分號(%)字符來表示任意字符,類似于UNIX或正則表達式中的星號 (*)。
如果沒有使用百分號(%), LIKE 子句與等號(=)的效果是一樣的。
語法
以下是SQL SELECT 語句使用 LIKE 子句從數(shù)據(jù)表中讀取數(shù)據(jù)的通用語法:
SELECT field1,field2,...fieldN FROM table_name1,table_name2...WHERE field1 LIKE condition1[AND[OR]]filed2='somevalue'
2、union語句
MySQL UNION 操作符用于連接兩個以上的 SELECT 語句的結(jié)果組合到一個結(jié)果集合中。多個 SELECT 語句會刪除重復(fù)的數(shù)據(jù)。
SELECT expression1,expression2,...expression_n
FROM tables[WHERE conditions]UNION[ALL|DISTINCT]SELECT expression1,expression2,...expression_n
FROM tables[WHERE conditions];
參數(shù)
expression1, expression2, ... expression_n: 要檢索的列。
tables:要檢索的數(shù)據(jù)表。
WHERE conditions:可選, 檢索條件。
DISTINCT:可選,刪除結(jié)果集中重復(fù)的數(shù)據(jù)。默認(rèn)情況下 UNION 操作符已經(jīng)刪除了重復(fù)數(shù)據(jù),所以 DISTINCT 修飾符對結(jié)果沒啥影響。
ALL:可選,返回所有結(jié)果集,包含重復(fù)數(shù)據(jù)。
3、order by 和group by
order by:設(shè)定你想按哪個字段哪中方式來進行排序,再返回搜索結(jié)果。即按照某個字段升序降序等。
SELECT field1,field2,...fieldN table_name1,table_name2...ORDER BY field1,[field2...][ASC[DESC]]
group by:根據(jù)一個或多個列對結(jié)果集進行分組。在分組的列上我們可以使用 COUNT, SUM, AVG,等函數(shù)。“SELECT name,COUNT(*)FROM? employee_tbl GROUP BY name;”表示將數(shù)據(jù)表按名字進行分組,并統(tǒng)計每個人有多少條記錄。
4、連接的使用:
INNER JOIN(內(nèi)連接,或等值連接):獲取兩個表中字段匹配關(guān)系的記錄。
LEFT JOIN(左連接):獲取左表所有記錄,即使右表沒有對應(yīng)匹配的記錄。
RIGHT JOIN(右連接):與 LEFT JOIN 相反,用于獲取右表所有記錄,即使左表沒有對應(yīng)匹配的記錄。
舉例如下:
--------------------------------------------
表A記錄如下:
aID aNum
1 a20050111
2 a20050112
3 a20050113
4 a20050114
5 a20050115
表B記錄如下:
bID bName
1 2006032401
2 2006032402
3 2006032403
4 2006032404
8 2006032408
--------------------------------------------
1.left join
sql語句如下:
select * from A
left join B
on A.aID = B.bID
結(jié)果如下:
aID aNum bID bName
1 a20050111 1 2006032401
2 a20050112 2 2006032402
3 a20050113 3 2006032403
4 a20050114 4 2006032404
5 a20050115 NULL NULL
(所影響的行數(shù)為 5 行)
結(jié)果說明:
left join是以A表的記錄為基礎(chǔ)的,A可以看成左表,B可以看成右表,left join是以左表為準(zhǔn)的.
換句話說,左表(A)的記錄將會全部表示出來,而右表(B)只會顯示符合搜索條件的記錄(例子中為: A.aID = B.bID).
B表記錄不足的地方均為NULL.
--------------------------------------------
2.right join
sql語句如下:
select * from A
right join B
on A.aID = B.bID
結(jié)果如下:
aID aNum bID bName
1 a20050111 1 2006032401
2 a20050112 2 2006032402
3 a20050113 3 2006032403
4 a20050114 4 2006032404
NULL NULL 8 2006032408
(所影響的行數(shù)為 5 行)
結(jié)果說明:
仔細(xì)觀察一下,就會發(fā)現(xiàn),和left join的結(jié)果剛好相反,這次是以右表(B)為基礎(chǔ)的,A表不足的地方用NULL填充.
--------------------------------------------
3.inner join
sql語句如下:
select * from A
innerjoin B
on A.aID = B.bID
結(jié)果如下:
aID aNum bID bName
1 a20050111 1 2006032401
2 a20050112 2 2006032402
3 a20050113 3 2006032403
4 a20050114 4 2006032404
結(jié)果說明:
很明顯,這里只顯示出了 A.aID = B.bID的記錄.這說明inner join并不以誰為基礎(chǔ),它只顯示符合條件的記錄.
5、外鍵與級聯(lián)操作
如果A表的一個字段m是B表的主鍵字段,則字段m就叫做A表的外鍵:因為A表的某一條記錄可由m來唯一確定它在B表的對應(yīng)記錄。外鍵的作用是建立表與表之間的關(guān)系,保證數(shù)據(jù)的完整性。如A表為:學(xué)號|學(xué)生姓名|班級|住址|年齡|,B表為:學(xué)號|選課編號,C表為:課程編號|課程名稱|學(xué)分
則學(xué)號為A表的主鍵,學(xué)號和選課編號為B表的聯(lián)合主鍵,課程編號為C表的主鍵。
由B表的學(xué)號字段可唯一確定A表的一條數(shù)據(jù),由B表的選課編號可唯一確定C表的一條數(shù)據(jù),則稱學(xué)號和選課編號都是B表的外鍵,分別對應(yīng)A表和B表。外鍵數(shù)據(jù)完整性體現(xiàn)在:它可以設(shè)置父表更新時子表也更新,父表刪除時如果子表有匹配的項,刪除失敗(或者父表更新時子表也更新,父表刪除時子表匹配的項也刪除等),更新可以保證數(shù)據(jù)一致性,刪除限制可以保證數(shù)據(jù)的完整性,不會出現(xiàn)垃圾數(shù)據(jù)。
MySQL支持外鍵的存儲引擎只有InnoDB,在創(chuàng)建外鍵的時候,要求父表必須有對應(yīng)的索引,子表在創(chuàng)建外鍵的時候也會自動創(chuàng)建對應(yīng)的索引。在創(chuàng)建索引的時候,可以指定在刪除、更新父表時,對子表進行的相應(yīng)操作,包括RESTRICT、NO ACTION、SET NULL和CASCADE。其中RESTRICT和NO ACTION相同,是指在子表有關(guān)聯(lián)記錄的情況下父表不能更新;CASCADE表示父表在更新或者刪除時,更新或者刪除子表對應(yīng)記錄;SET NULL則是表示父表在更新或者刪除的時候,子表的對應(yīng)字段被SET NULL。
創(chuàng)建數(shù)據(jù)庫:
Create database test;
創(chuàng)建兩個表,其中第一個表的”id”是第二個表(userinfo)的外鍵:
CREATE TABLE `user` (
`id` int(4) NOT NULL,
`sex` enum('f','m') DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `userinfo` (
`sn` int(4) NOT NULL AUTO_INCREMENT,
`userid` int(4) NOT NULL,
`info` varchar(20) DEFAULT NULL,
PRIMARY KEY (`sn`),
KEY `userid` (`userid`),
CONSTRAINT `userinfo_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
注意:
1、存儲引擎必須使用InnoDB引擎;
2、外鍵必須建立索引;
3、外鍵綁定關(guān)系這里使用了“?ON?DELETE?CASCADE ” “ON UPDATE CASCADE”,意思是如果外鍵對應(yīng)數(shù)據(jù)被刪除或者更新時,將關(guān)聯(lián)數(shù)據(jù)完全刪除或者相應(yīng)地更新。更多信息請參考MySQL手冊中關(guān)于InnoDB的文檔;
好,接著我們再來插入數(shù)據(jù)測試:
INSERT?INTO?`user`?(`id`,`sex`)
VALUES?('1',?'f'),??('2',?'m'),?('3',?'f');
INSERT?INTO?`userinfo`?(`sn`,`userid`,`info`)
VALUES ?('1',?'1',?'2005054dsf'),
('2',?'1',?'fdsfewfdsfds'),
('3',?'1',?'gdsgergergrtre'),
('4',?'2',?'et34t5435435werwe'),
('5',?'2',?'435rtgtrhfghfg'),
('6',?'2',?'ret345tr4345'),
('7',?'3',?'fgbdfvbcbfdgr'),
('8',?'3',?'45r2343234were'),
('9',?'3',?'wfyhtyjtyjyjy');
我們先看一下當(dāng)前數(shù)據(jù)表的狀態(tài):
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| user?????????? |
| userinfo?????? |
+----------------+
2 rows in set (0.00 sec)
User表中的數(shù)據(jù):
mysql> select * from user;
+----+------+
| id | sex? |
+----+------+
|? 1 | f??? |
|? 2 | m??? |
|? 3 | f??? |
+----+------+
3 rows in set (0.00 sec)
Userinfo表中的數(shù)據(jù):
mysql> select * from userinfo;
+----+--------+-------------------+
| sn | userid | info????????????? |
+----+--------+-------------------+
|? 1 |????? 1 | 2005054dsf??????? |
|? 2 |????? 1 | fdsfewfdsfds????? |
|? 3 |????? 1 | gdsgergergrtre??? |
|? 4 |????? 2 | et34t5435435werwe |
|? 5 |????? 2 | 435rtgtrhfghfg??? |
|? 6 |????? 2 | ret345tr4345????? |
|? 7 |????? 3 | fgbdfvbcbfdgr???? |
|? 8 |????? 3 | 45r2343234were??? |
|? 9 |????? 3 | wfyhtyjtyjyjy???? |
+----+--------+-------------------+
9 rows in set (0.00 sec)
下面我們就要試驗我們的級聯(lián)刪除功能了。
我們將刪除user表中id為2的數(shù)據(jù)記錄,看看userinf表中userid為2的相關(guān)子紀(jì)錄是否會自動刪除:
執(zhí)行刪除操作成功!
mysql> delete from `user` where `id`='2';
Query OK, 1 row affected (0.03 sec)
看看user表中已經(jīng)沒有id為2的數(shù)據(jù)記錄了!
mysql> select * from user;
+----+------+
| id | sex? |
+----+------+
|? 1 | f??? |
|? 3 | f??? |
+----+------+
2 rows in set (0.00 sec)
再看看userinfo表中已經(jīng)沒有userid為2的3條數(shù)據(jù)記錄了,對應(yīng)數(shù)據(jù)確實自動刪除了!
mysql> select * from userinfo;
+----+--------+----------------+
| sn | userid | info?????????? |
+----+--------+----------------+
|? 1 |????? 1 | 2005054dsf???? |
|? 2 |????? 1 | fdsfewfdsfds?? |
|? 3 |????? 1 | gdsgergergrtre |
|? 7 |????? 3 | fgbdfvbcbfdgr? |
|? 8 |????? 3 | 45r2343234were |
|? 9 |????? 3 | wfyhtyjtyjyjy? |
+----+--------+----------------+
6 rows in set (0.00 sec)
更新的操作也類似,因為我們在前面建表的時候已經(jīng)定義外鍵刪除、更新操作都是CASCADE,所以在這里可以直接測試數(shù)據(jù)。
將user表中原來id為1的數(shù)據(jù)記錄更改為id為4,執(zhí)行如下:
mysql> update user set id=4 where id='1';
Query OK, 1 row affected (0.03 sec)
Rows matched: 1? Changed: 1? Warnings: 0
現(xiàn)在去看看兩個表中是數(shù)據(jù)是否發(fā)生了變化:
mysql> select * from user;
+----+------+
| id | sex? |
+----+------+
|? 3 | f??? |
|? 4 | f??? |
+----+------+
2 rows in set (0.00 sec)
mysql> select * from userinfo;
+----+--------+----------------+
| sn | userid | info?????????? |
+----+--------+----------------+
|? 1 |????? 4 | 2005054dsf???? |
|? 2 |????? 4 | fdsfewfdsfds?? |
|? 3 |????? 4 | gdsgergergrtre |
|? 7 |????? 3 | fgbdfvbcbfdgr? |
|? 8 |????? 3 | 45r2343234were |
|? 9 |????? 3 | wfyhtyjtyjyjy? |
+----+--------+----------------+
6 rows in set (0.00 sec)
比較原來的表可以發(fā)現(xiàn)它們的確已經(jīng)更新成功了,測試完成!!!這也就實現(xiàn)了用外鍵對多個相關(guān)聯(lián)的表做同時刪除、更新的操作,從而保證了數(shù)據(jù)的一致性。
6、索引
索引用于快速找出在某個列中有一特定值的行。不使用索引,MySQL必須從第1條記錄開始然后讀完整個表直到找出相關(guān)的行。表越大,花費的時間越多。如果表中查詢的列有一個索引,MySQL能快速到達一個位置去搜尋到數(shù)據(jù)文件的中間,沒有必要看所有數(shù)據(jù)。如果一個表有1000行,這比順序讀取至少快100倍。注意如果你需要訪問大部分行,順序讀取要快得多,因為此時我們避免磁盤搜索。
例如對下面這樣的一個student表:
mysql>SELECT * FROM student
+——+———+———+———+———+
| id?? | name????| english | chinese | history |
+——+———+———+———+———+
|?? 12 | Tom???? |??????66 |??????93 |??????67 |
|?? 56 | Paul????|??????78 |??????52 |??????75 |
|?? 10 | Marry?? |??????54 |??????89 |??????74 |
|????4 | Tina????|??????99 |??????83 |??????48 |
|?? 39 | William |??????43 |??????96 |??????52 |
|?? 74 | Stone?? |??????42 |??????40 |??????61 |
|?? 86 | Smith?? |??????49 |??????85 |??????78 |
|?? 37 | Black?? |??????49 |??????63 |??????47 |
|?? 89 | White?? |??????94 |??????31 |??????52 |
+——+———+———+———+———+
這樣,我們試圖對它進行一個特定查詢時,就不得不做一個全表的掃描,速度很慢。
例如,我們查找出所有english成績不及格的學(xué)生:
mysql>SELECT name,english FROM student WHERE english<60;
+———+———+
| name????| english |
+———+———+
| Marry?? |??????54 |
| William |??????43 |
| Stone?? |??????42 |
| Smith?? |??????49 |
| Black?? |??????49 |
+———+———+
其中,WHERE從句不得不匹配每個記錄,以檢查是否符合條件。對于這個較小的表也許感覺不到太多的影響。但是對于一個較大的表,例如一個非常大的學(xué)校,我們可能需要存儲成千上萬的記錄,這樣一個檢索的所花的時間是十分可觀的。
如果,我們?yōu)閑nglish列創(chuàng)建一個索引:
mysql>ALTER TABLE student ADD INDEX (english) ;
+——————-+
| index for english |
+——————-+
|????????????????42 |
|????????????????43 |
|????????????????49 |
|????????????????49 |
|????????????????54 |
|????????????????66 |
|????????????????78 |
|????????????????94 |
|????????????????99 |
+——————-+
如上表,此索引存儲在索引文件中,包含表中每行的english列值,但此索引是在 english的基礎(chǔ)上排序的。現(xiàn)在,不需要逐行搜索全表查找匹配的條款,而是可以利用索引進行查找。
假如我們要查找分?jǐn)?shù)小于60的所有行,那么可以掃描索引,結(jié)果得出5行。然后到達分?jǐn)?shù)為66的行,及Tom的記錄,這是一個比我們正在查找的要大的值。
索引值是排序的,因此在讀到包含Tom的記錄時,我們知道不會再有匹配的記錄,可以退出了。
如果查找一個值,它在索引表中某個中間點以前不會出現(xiàn),那么也有找到其第一個匹配索引項的定位算法,而不用進行表的順序掃描(如二分查找法)。
五、數(shù)據(jù)庫存儲引擎
1、什么是存儲引擎呢?
存儲引擎說白了就是如何存儲數(shù)據(jù)、如何為存儲的數(shù)據(jù)建立索引和如何更新、查詢數(shù)據(jù)等技術(shù)的實現(xiàn)方法。因為在關(guān)系數(shù)據(jù)庫中數(shù)據(jù)的存儲是以表的形式存儲的,所以存儲引擎也可以稱為表類型(即存儲和操作此表的類型)。
在Oracle 和SQL Server等數(shù)據(jù)庫中只有一種存儲引擎,所有數(shù)據(jù)存儲管理機制都是一樣的。而MySql數(shù)據(jù)庫提供了多種存儲引擎。用戶可以根據(jù)不同的需求為數(shù)據(jù)表選擇不同的存儲引擎,用戶也可以根據(jù)自己的需要編寫自己的存儲引擎。
2、MySql的存儲引擎
(1)MyISAM:這種引擎是mysql最早提供的。這種引擎又可以分為靜態(tài)MyISAM、動態(tài)MyISAM 和壓縮MyISAM三種:
靜態(tài)MyISAM:如果數(shù)據(jù)表中的各數(shù)據(jù)列的長度都是預(yù)先固定好的,服務(wù)器將自動選擇這種表類型。因為數(shù)據(jù)表中每一條記錄所占用的空間都是一樣的,所以這種表存取和更新的效率非常高。當(dāng)數(shù)據(jù)受損時,恢復(fù)工作也比較容易做。
動態(tài)MyISAM:如果數(shù)據(jù)表中出現(xiàn)varchar、xxxtext或xxxBLOB字段時,服務(wù)器將自動選擇這種表類型。相對于靜態(tài)MyISAM,這種表存儲空間比較小,但由于每條記錄的長度不一,所以多次修改數(shù)據(jù)后,數(shù)據(jù)表中的數(shù)據(jù)就可能離散的存儲在內(nèi)存中,進而導(dǎo)致執(zhí)行效率下降。同時,內(nèi)存中也可能會出現(xiàn)很多碎片。因此,這種類型的表要經(jīng)常用optimize table 命令或優(yōu)化工具來進行碎片整理。
壓縮MyISAM:以上說到的兩種類型的表都可以用myisamchk工具壓縮。這種類型的表進一步減小了占用的存儲,但是這種表壓縮之后不能再被修改。另外,因為是壓縮數(shù)據(jù),所以這種表在讀取的時候要先時行解壓縮。
但是,不管是何種MyISAM表,目前它都不支持事務(wù),行級鎖和外鍵約束的功能。
(2)MyISAM Merge引擎:這種類型是MyISAM類型的一種變種。合并表是將幾個相同的MyISAM表合并為一個虛表。常應(yīng)用于日志和數(shù)據(jù)倉庫。
(3)InnoDB:InnoDB表類型可以看作是對MyISAM的進一步更新產(chǎn)品,它提供了事務(wù)、行級鎖機制和外鍵約束的功能。
(4)memory(heap):這種類型的數(shù)據(jù)表只存在于內(nèi)存中。它使用散列索引,所以數(shù)據(jù)的存取速度非常快。因為是存在于內(nèi)存中,所以這種類型常應(yīng)用于臨時表中。
(5) archive:這種類型只支持select 和 insert語句,而且不支持索引。常應(yīng)用于日志記錄和聚合分析方面。
2、存儲引擎的選擇
MySQL有多種存儲引擎,MyISAM和InnoDB是其中常用的兩種。
MyISAM是MySQL的默認(rèn)存儲引擎,基于傳統(tǒng)的ISAM類型,支持全文搜索,但不是事務(wù)安全的,而且不支持外鍵。每張MyISAM表存放在三個文件中:frm 文件存放表格定義;數(shù)據(jù)文件是MYD (MYData);索引文件是MYI (MYIndex)。 InnoDB是事務(wù)型引擎,支持回滾、崩潰恢復(fù)能力、多版本并發(fā)控制、ACID事務(wù),支持行級鎖定(InnoDB表的行鎖不是絕對的,如果在執(zhí)行一個SQL語句時MySQL不能確定要掃描的范圍,InnoDB表同樣會鎖全表,如like操作時的SQL語句),以及提供與Oracle類型一致的不加鎖讀取方式。InnoDB存儲它的表和索引在一個表空間中,表空間可以包含數(shù)個文件。
主要區(qū)別:
MyISAM是非事務(wù)安全型的,而InnoDB是事務(wù)安全型的。
MyISAM鎖的粒度是表級,而InnoDB支持行級鎖定。
MyISAM支持全文類型索引,而InnoDB不支持全文索引。
MyISAM相對簡單,所以在效率上要優(yōu)于InnoDB,小型應(yīng)用可以考慮使用MyISAM。
MyISAM表是保存成文件的形式,在跨平臺的數(shù)據(jù)轉(zhuǎn)移中使用MyISAM存儲會省去不少的麻煩。
InnoDB表比MyISAM表更安全,可以在保證數(shù)據(jù)不會丟失的情況下,切換非事務(wù)表到事務(wù)表(alter table tablename type=innodb)。
應(yīng)用場景:
MyISAM管理非事務(wù)表。它提供高速存儲和檢索,以及全文搜索能力。如果應(yīng)用中需要執(zhí)行大量的SELECT查詢,那么MyISAM是更好的選擇。
InnoDB用于事務(wù)處理應(yīng)用程序,具有眾多特性,包括ACID事務(wù)支持。如果應(yīng)用中需要執(zhí)行大量的INSERT或UPDATE操作,則應(yīng)該使用InnoDB,這樣可以提高多用戶并發(fā)操作的性能。
參考自:
1、http://www.runoob.com/mysql/mysql-tutorial.htmlhttp://blog.csdn.net/m8396017/article/details/51355211
2、http://www.cnblogs.com/pcjim/articles/799302.html
3、http://blog.csdn.net/sunzhenhua0608/article/details/8948120
4、http://doc.mysql.cn/mysql5/refman-5.1-zh.html-chapter/
5、http://www.cnblogs.com/ggjucheng/archive/2012/11/04/2754128.html
6、http://www.cnblogs.com/lina1006/archive/2011/04/29/2032894.html