必威电竞|足球世界杯竞猜平台

myisam
來源:互聯(lián)網

MyISAM是默認存儲引擎(MySQL5.1前)。它基于更老的ISAM代碼,但有很多有用的擴展。(注意MySQL 5.1不支持ISAM)。每個MyISAM在磁盤上存儲成三個文件,每一個文件的名字均以表的名字開始,擴展名指出文件類型。

.frm文件存儲表定義;

·MYD (MYData)文件存儲表的數據;

.MYI (MYIndex)文件存儲表的索引。

簡介

要明確表示你想要用一個MyISAM表格,請用ENGINE表選項指出來:

CREATE TABLE t (i INT) ENGINE = MYISAM;

注釋:老版本的MySQL使用TYPE而不是ENGINE(例如,TYPE = MYISAM)。MySQL 5.1為向下兼容而支持這個語法,但TYPE現(xiàn)在被輕視,而ENGINE是首先的用法。

一般地,ENGINE選項是不必要的;除非默認已經被改變了,InnoDB是默認存儲引擎(Mysql 5.1后)。

你可以用myisamchk工具來檢查或修復MyISAM表。請參閱MySQL 5.1參考手冊5.9.5.6節(jié),“使用myisamchk做崩潰恢復”。你也可以用myisampack來壓縮MyISAM表,讓它們占更少的空間。請參閱MySQL 5.1參考手冊8.2節(jié),“myisampack,產生壓縮、只讀的MyISAM表”。

特征

MyISAM存儲引擎的一些特征

1. 所有數據值先存儲低字節(jié)。這使得數據機和操作系統(tǒng)分離。二進制輕便性的唯一要求是機器使用補碼(如最近20年的機器有的一樣)和IEEE浮點格式(在主流機器中也完全是主導的)。唯一不支持二進制兼容性的機器是嵌入式系統(tǒng)。這些系統(tǒng)有時使用特殊的處理器。

先存儲數據低字節(jié)并不嚴重地影響速度;數據行中的字節(jié)一般是未聯(lián)合的,從一個方向讀未聯(lián)合的字節(jié)并不比從反向讀更占用更多的資源。服務器上的獲取列值的代碼與其它代碼相比并不顯得時間緊。

2.大文件(達63位文件長度)在支持大文件的文件系統(tǒng)和操作系統(tǒng)上被支持。

3. 當把刪除和更新及插入混合的時候,動態(tài)尺寸的行更少碎片。這要通過合并相鄰被刪除的塊,以及若下一個塊被刪除,就擴展到下一塊來自動完成。

7. NULL值被允許在索引的列中。這個占每個鍵的0-1個字節(jié)

8. 所有數字鍵值以高字節(jié)為先被存儲以允許一個更高地索引壓縮。

9. 當記錄以排好序的順序插入(就像你使用一個AUTO_INCREMENT列之時),索引樹被劈開以便高節(jié)點僅包含一個鍵。這改善了索引樹的空間利用率。

10.每表一個AUTO_INCREMENT列的內部處理。MyISAM為INSERT和UPDATE操作自動更新這一列。這使得AUTO_INCREMENT列更快(至少10%)。在序列頂的值被刪除之后就不能再利用。(當AUTO_INCREMENT列被定義為多列索引的最后一列,可以出現(xiàn)重使用從序列頂部刪除的值的情況)。AUTO_INCREMENT值可用ALTER TABLE或myisamch來重置。

11. 如果數據文件中間的表沒有自由塊了,在其它線程從表讀的同時,你可以INSERT新行到表中。(這被認識為并發(fā)操作)。自由塊的出現(xiàn)是作為刪除行的結果,或者是用比當前內容多的數據對動態(tài)長度行更新的結果。當所有自由塊被用完(填滿),未來的插入又變成并發(fā)。

12.你可以把數據文件和索引文件放在不同目錄,用DATA DIRECTORY和INDEX DIRECTORY選項CREATE TABLE以獲得更高的速度,請參閱13.1.5節(jié),“CREATE TABLE語法”。

a.每個字符列可以有不同的字符集,請參閱第10章:“字符集支持”。

b.在MyISAM索引文件里有一個標志,它表明表是否被正確關閉。如果用--myisam-recover選項啟動MySQLd,MyISAM表在打開得時候被自動檢查,如果被表被不恰當地關閉,就修復表。

c.如果你用--update-state選項運行myisamchk,它標注表為已檢查。myisamchk --500米口徑球面射電望遠鏡只檢查那些沒有這個標志的表。

d. myisamchk --analyze為部分鍵存儲統(tǒng)計信息,也為整個鍵存儲統(tǒng)計信息。

e. myisampack可以打包BLOB和VARCHAR列。

MyISAM也支持下列特征

1.支持true VARCHAR類型;VARCHAR列以存儲在2個字節(jié)中的長度來開始。

2.有VARCHAR的表可以有固定或動態(tài)記錄長度。

3. VARCHAR和CHAR列可以多達64KB。

4. 一個被搞亂的已計算索引對可對UNIQUE來使用。這允許你在表內任何列的合并上有UNIQUE。(盡管如此,你不能在一個UNIQUE已計算索引上搜索)。

對MyISAM存儲引擎,有一個更詳細的論壇在

15.1.1. MyISAM啟動選項

下列對mysqld 的選項可用來改變MyISAM表的行為:

· --myisam-recover=mode

設置為崩潰MyISAM表自動恢復的模式。

· --delay-key-write=ALL

對任何MyISAM表的寫操作之間不要刷新鍵緩沖區(qū)。

注釋:如果你要這么做。當表在使用中之時,你應該不使用來自另一個程序的MyISAM表(比如從另一個MySQL服務器或用myisamchk)。這么做會導致索引被破壞。

對使用--delay-key-write的表,使用--external-locking沒有幫助。

請參閱5.3.1節(jié),“mysqld命令行選項”。

下列系統(tǒng)變量影響MyISAM表的行為:

· bulk_insert_buffer_size

用在塊插入優(yōu)化中的樹緩沖區(qū)的大小。注釋:這是一個per thread的限制。

· (OBSOLETE) myisam_max_extra_sort_file_size

這個參數已經不在MySQL中使用。

· myisam_max_sort_file_size

如果臨時文件會變得超過索引,不要使用快速排序索引方法來創(chuàng)建一個索引。注釋:這個參數以字節(jié)的形式給出。

· myisam_sort_buffer_size

設置恢復表之時使用的緩沖區(qū)的尺寸。

請參閱5.3.3節(jié),“服務器系統(tǒng)變量”。

如果用--myisam-recover選項啟動mysqld,自動恢復被激活。在這種情況下,當服務器打開一個MyISAM表之時,服務器會檢查是否表被標注為崩潰,或者表的打開計數變量是否不為0且你正用--skip-external-locking運行服務器。如果這些條件的任何一個為真,下列情況發(fā)生:

· 表被查錯。

· 如果服務器發(fā)現(xiàn)一個錯誤,它試著做快速表修復(排序且不重新創(chuàng)建數據文件)。

· 如果修復因為數據文件中的一個錯誤而失敗(例如,一個重復鍵錯誤),服務器會再次嘗試修復,這一次重建數據文件。

· 如果修復仍然失敗,服務器用舊修復選項方法再重試一次修復(一行接一行地寫,不排序)。這個方法應該能修復任何類型的錯誤,并且需要很低的磁盤空間。

如果恢復不能夠從先前完成的語句里恢復所有行,而且你不能在--myisam-recover選項值指定FORCE,自動修復會終止,并在錯誤日志里寫一條錯誤信息:

Error: Couldn't repair table: test.g00pages

如果你指定FORCE,取而代之地,類似這樣的一個警告被給出:

Warning: Found 344 of 354 rows when repairing ./test/g00pages

注釋:如果自動恢復值包括BACKUP,恢復進程創(chuàng)建文件并用tbl_name-datetime.BAK形式取名。你應該有一個cron腳本,它自動把這些文件從數據庫目錄移到備份媒質上。

15.1.2.鍵所需的空間

MyISAM表使用B型樹索引。你可以粗略地計算索引文件的大小為(key_length+4)/0.67, 加上所有的鍵之和。當所有鍵以排序的順序插入并且表沒有任何壓縮的鍵之時,以上估計是對最壞的情況的。

字符串索引是被空間壓縮的。如果第一個字符串索引部分是字符串,它也被加前綴壓縮。如果字符串列有許多拖曳空間,或字符串列是一個總是不用完全長度的VARCHAR列,空間壓縮使得索引文件比最壞情況時的數值要小。前綴壓縮被用在以字符串開始的鍵上。如果有許多具有同一前綴的字符串,前綴壓縮是有幫助的。

在MyISAM表,你也可以在創(chuàng)建表的時候通過指定PACK_KEYS=1來前綴壓縮數字。當數字被以高字節(jié)優(yōu)先存儲之時,若你有許多具有同一前綴的整數鍵,上述方法是有幫助的。

存儲格式

MyISAM支持三種不同存儲格式。

其中兩個(固定格式和動態(tài)格式)根據正使用的列的類型來自動選擇。第三個,即已壓縮格式,只能使用myisampack工具來創(chuàng)建。

當你CREATE或ALTER一個沒有BLOB或TEXT列的表,你可以用ROW_FORMAT表選項強制表的格式為FIXED或DYNAMIC。這會導致CHAR和VARCHAR列因FIXED格式變成CHAR,或因DYNAMIC格式變成VARCHAR。

靜態(tài)表

(固定長度)

靜態(tài)格式是MyISAM表的默認存儲格式。當表不包含變量長度列(VARCHAR, BLOB, 或TEXT)時,使用這個格式。每一行用固定字節(jié)數存儲。

MyISAM的三種存儲格式中,靜態(tài)格式就最簡單也是最安全的(至少對于崩潰而言)。靜態(tài)格式也是最快的on-disk格式。快速來自于數據文件中的行在磁盤上被找到的容易方式:當按照索引中的行號查找一個行時,用行長度乘以行號。同樣,當掃描一個表的時候,很容易用每個磁盤讀操作讀一定數量的記錄。

MySQL服務器正往一個固定格式MyISAM文件寫的時候,如果計算機崩潰了,安全是顯然的。在這種情況下,myisamchk可以容易地決定每行從哪里開始到哪里結束,所以它通常可以收回所有記錄,除了寫了一部分的記錄。注意,基于數據行,MyISAM表索引可以一直被重新構建。

靜態(tài)格式表的一般特征:

· CHAR列對列寬度是空間填補的。

· 非常快。

· 容易緩存

· 崩潰后容易重建,因為記錄位于固定位置。

· 重新組織是不必要的,除非你刪除巨量引擎的記錄并且希望為操作系統(tǒng)騰出磁盤空間。為此,可使用OPTIMIZE TABLE或者myisamchk -r。

· 通常比動態(tài)格式表需要更多的磁盤空間。

動態(tài)表

如果一個MyISAM表包含任何可變長度列(VARCHAR, BLOB或TEXTDynamic),或者如果一個表被用ROW_FORMAT=DYNAMIC選項來創(chuàng)建,動態(tài)存儲格式被使用。

這個格式更為復雜一點,因為每行有一個表明行有多長的頭。當一個記錄因為更新的結果被變得更長,該記錄也可以在超過一個位置處結束。

你可以使用OPTIMIZE TABLE或myisamchk來對一個表整理碎片。如果在一個表中有你頻繁訪問或改變的固定長度列,表中也有一些可變長度列,僅為避免碎片而把這些可變長度列移到其它表可能是一個好主意。

動態(tài)格式表的一般特征:

· 除了長度少于4的列外,所有的字符串列是動態(tài)的。

· 在每個記錄前面是一個位圖,該位圖表明哪一列包含空字符串(對于字符串列)或者0(對于數字列)。注意,這并不包括包含NULL值的列。如果一個字符列在拖曳空間移除后長度為零,或者一個數字列為零值,這都在位圖中標注了且列不被保存到磁盤。非空字符串被存為一個長度字節(jié)加字符串的內容。

· 通常比固定長度表需要更少的磁盤空間。

· 每個記錄僅使用必需大小的空間。盡管如此,如果一個記錄變大,它就按需要被分開成多片,造成記錄碎片的后果。比如,你用擴展行長度的信息更新一行,該行就變得有碎片。在這種情況下,你可以時不時運行OPTIMIZE TABLE或myisamchk -r來改善性能。可使用myisamchk -ei來獲取表的統(tǒng)計數據。

· 動態(tài)格式表在崩潰后要比靜態(tài)格式表更難重建,因為一個記錄可能被分為多個碎片且鏈接(碎片)可能被丟失。

· 動態(tài)尺寸記錄期望的行長度用下列表達式來計算:

· 3

· + (number of columns + 7) / 8

· + (number of char columns)

· + (packed size of numeric columns)

· + (length of strings)

· + (number of NULL columns + 7) / 8

對每個鏈接需要額外的6字節(jié)。在一個更新導致一個記錄的擴大之時,一個動態(tài)記錄被鏈接了。每個新鏈接至少是20字節(jié),所以下一個擴大可能在同樣的鏈接里進行。如果不是,則另一個鏈接將被建立。你可以使用myisamchk -ed來找出鏈接的數目。所有的鏈接可以用myisamchk -r來移除。

已壓縮表

已壓縮存儲格式是由myisampack工具創(chuàng)建的只讀格式。

所有MySQL分發(fā)版里都默認包括myisampack。已壓縮表可以用myisamchk來解壓縮。

已壓縮表有下列特征:

· 已壓縮表占據非常小的磁盤空間。這最小化了磁盤用量,當使用緩慢的磁盤(如CD-ROM)之時,這是很有用的。

· 每個記錄是被單獨壓縮的,所以只有非常小的訪問開支。依據表中最大的記錄,一個記錄的頭在每個表中占據1到3個字節(jié)。每個列被不同地壓縮。通常每個列有一個不同的Huffman樹。一些壓縮類型如下:

o 后綴空間壓縮。

- 前綴空間壓縮。

- 零值的數用一個位來存儲。

- 如果在一個整型列中的值有一個小的范圍,列被用最小可能的類型來存儲。比如,一個BIGINT列(8字節(jié)),如果所有它的值在-128到127范圍內,它可以被存儲為TINYINT列(1字節(jié))

- 如果一個列僅有一小組可能的值,列的類型被轉化成ENUM。

- 一個列可以使用先前壓縮類型的任意合并。

· 可以處理固定長度或動態(tài)長度記錄。

問題

MySQL用來存儲數據的文件格式已經被廣泛測試過,但總是有導致數據表變得損壞的環(huán)境。

損壞的MyISAM表

即使MyISAM表格式非常可靠(SQL對表做的所有改變在語句返回之前被寫下),如果下列任何事件發(fā)生,你依然可以獲得損壞的表:

· mysqld進程在寫中間被殺掉。

· 發(fā)生未預期的計算機關閉(例如,計算機被關閉)。

· 硬件故障。

· 你可以同時在正被服務器修改的表上使用外部程序(如myisamchk)。

· MySQL或MyISAM代碼的軟件缺陷。

一個損壞的表的典型癥狀如下:

· 當在從表中選擇數據之時,你得到如下錯誤:

· Incorrect key file for table: '...'. Try to repair it

· 查詢不能在表中找到行或返回不完全的數據。

你可以用CHECK TABLE statement語句來檢查MyISAM表的健康,并用REPAIR TABLE修復一個損壞的MyISAM表。當mysqld不運行之時,你也可以用myisamchk命令檢查或修理一個表。請參閱13.5.2.3節(jié),“CHECK TABLE語法”, 13.5.2.6節(jié),“REPAIR TABLE語法”,和5.9.5節(jié),“myisamchk — MyISAM表維護工具”。

如果你的表變得頻繁損壞,你應該試著確定為什么會這樣的原因。要明白的最重要的事是表變得損壞是不是因為服務器崩潰的結果。你可以在錯誤日志中查找最近的restarted mysqld消息來早期驗證這個。如果存在這樣一個消息,則表損壞是服務器死掉的一個結果是很有可能的。否則,損壞可能在正常操作中發(fā)生。這是一個缺陷。你應該試著創(chuàng)建一個展示這個問題的可重復生成的測試案例。請參閱A.4.2節(jié),“如果MySQL保持崩潰,該怎么做”及E.1.6節(jié),“如果出現(xiàn)表崩潰,請生成測試案例”。

未被適當關閉的表的問題

每個MyISAM索引文件(.MYI)在頭有一個計數器,它可以被用來檢查一個表是否被恰當地關閉。如果你從CHECK TABLE或myisamchk得到下列警告,意味著這個計數器已經不同步了:

clients are using or haven't closed the table properly

這個警告并不是完全意味著表已被破壞,但你至少應該檢查表。

計數器的工作方式如下:

· 表在MySQL中第一次被更新,索引文件頭的計數器加一。

· 在未來的更新中,計數器不被改變。

· 當表的最后實例被關閉(因為一個操作FLUSH TABLE或因為在表緩沖區(qū)中沒有空間)之時,若表已經在任何點被更新,則計數器減一。

· 當你修理或檢查表并且發(fā)現(xiàn)表完好之時,計數器被重置為零。

· 要避免與其它可能檢查表的進程進行事務的問題,若計數器為零,在關閉時計數器不減一。

換句話來說,計數器只有在下列情況會不同步:

· MyISAM表不隨第一次發(fā)出的LOCK TABLES和FLUSH TABLES被復制。

· MySQL在一次更新和最后關閉之間崩潰(注意,表可能依然完好,因為MySQL總是在每個語句之間為每件事發(fā)出寫操作)。

· 一個表被myisamchk --recover或myisamchk --update-state修改,同時被mysqld使用。

· 多個mysqld服務器正使用表,并且一個服務器在一個表上執(zhí)行REPAIR TABLE或CHECK TABLE,同時該表也被另一個服務器使用。在這個結構中,使用CHECK TABLE是安全的,雖然你可能從其它服務器上得到警告。盡管如此,REPAIR TABLE應該被避免,因為當一個服務器用一個新的數據文件替代舊的之時,這并沒有發(fā)送信號到其它服務器上。

總的來說,在多服務器之間分享一個數據目錄是一個壞主意。

參考資料 >

生活家百科家居網