【Mysql 學習】MyISAM儲存引擎(二)。

楊奇龍發表於2011-01-05

MyISAM表的儲存格式
1. 靜態(固定長度)表特徵
2. 動態表特徵
3. 已壓縮表特徵
  MyISAM支援三種不同儲存格式。其中兩個(固定格式和動態格式)根據正使用的列的型別來自動選擇。第三個,即已壓縮格式,只能使用myisampack工具來建立。
   當CREATE或ALTER一個沒有BLOB或TEXT列的表,可以用ROW_FORMAT表選項強制表的格式為FIXED或DYNAMIC。這會導致CHAR和VARCHAR列因FIXED格式變成CHAR,或因DYNAMIC格式變成VARCHAR。
透過用ALTER TABLE指定ROW_FORMAT={COMPRESSED | DEFAULT},可以壓縮或解壓縮表,

15.1.3.1. 靜態(固定長度)表特徵
  靜態格式是MyISAM表的預設儲存格式。當表不包含變數長度列(VARCHAR, BLOB, 或TEXT)時,使用這個格式。每一行用固定位元組數儲存。

  MyISAM的三種儲存格式中,靜態格式就最簡單也是最安全的(至少對於崩潰而言)。靜態格式也是最快的on-disk格式。快速來自於資料檔案中的行在磁碟上被找到的容易方式:當按照索引中的行號查詢一個行時,用行長度乘以行號。同樣,當掃描一個表的時候,很容易用每個磁碟讀操作讀一定數量的記錄。
  當MySQL伺服器正往一個固定格式MyISAM檔案寫的時候,如果計算機崩潰了,安全是顯然的。在這種情況下,myisamchk可以容易地決定每行從哪裡開始到哪裡結束,所以它通常可以收回所有記錄,除了寫了一部分的記錄。注意,基於資料行,MyISAM表索引可以一直被重新構建。

靜態格式表的一般特徵:
·CHAR列對列寬度是空間填補的。
·非常快。
·容易快取。
·崩潰後容易重建,因為記錄位於固定位置。
·重新組織是不必要的,除非你刪除巨量的記錄並且希望為作業系統騰出磁碟空間。為此,可使用OPTIMIZE TABLE或者myisamchk -r。
·通常比動態格式表需要更多的磁碟空間。
靜態表的資料在儲存的收穫會按照列的寬度定義補足空格,但是在應用訪問的時候並不會得到這些空格,這些空格在返回給應用程式之前就被去掉了。

mysql> insert into myisam_char values('abcde'),('  abcde'),('yangql '),(' xxq ');
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> select val ,length(val) from myisam_char;
+---------+-------------+
| val     | length(val) |
+---------+-------------+
| abcde   |           5 |
|   abcde |           7 |-前面的空格保留
| yangql  |           6 |-空格被去掉
|  xxq    |           4 |-空格被去掉
+---------+-------------+
4 rows in set (0.00 sec)
15.1.3.2. 動態表特徵
  如果一個MyISAM表包含任何可變長度列(VARCHAR, BLOB或TEXTDynamic),或者如果一個表被用ROW_FORMAT=DYNAMIC選項來建立,動態儲存格式被使用。
   動態表的格式比較複雜,因為每行有一個表明行有多長的頭。當一個記錄因為更新的結果被變得更長,該記錄也可以在超過一個位置處結束。
  你可以使用OPTIMIZE TABLE或myisamchk來對一個表整理碎片。如果在一個表中有你頻繁訪問或改變的固定長度列,表中也有一些可變長度列,僅為避免碎片而把這些可變長度列移到其它表。

動態格式表的一般特徵:
·除了長度少於4的列外,所有的字串列是動態的。
·在每個記錄前面是一個點陣圖,該點陣圖表明哪一列包含空字串(對於字串列)或者0(對於數字列)。注意,這並不包括包含NULL值的列。如果一個字元列在拖曳空間移除後長度為零,或者一個數字列為零值,這都在點陣圖中標註了且列不被儲存到磁碟。 非空字串被存為一個長度位元組加字串的內容。
·通常比固定長度表需要更少的磁碟空間。
·每個記錄僅使用必需大小的空間。儘管如此,如果一個記錄變大,它就按需要被分開成多片,造成記錄碎片的後果。比如,你用擴充套件行長度的資訊更新一行,該行就變得有碎片。在這種情況下,你可以時不時執行OPTIMIZE TABLE或myisamchk -r來改善效能。可使用myisamchk -ei來獲取表的統計資料。

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

·動態尺寸記錄期望的行長度用下列表示式來計算:

·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位元組。在一個更新導致一個記錄的擴大之時,一個動態記錄被連結了。每個新連結至少是20位元組,所以下一個擴大可能在同樣的連結裡進行。如果不是,則另一個連結將被建立。你可以使用myisamchk -ed來找出連結的數目。所有的連結可以用myisamchk -r來移除。


15.1.3.3. 已壓縮表特徵
已壓縮儲存格式是由myisampack工具建立的只讀格式。
所有MySQL分發版裡都預設包括myisampack。已壓縮表可以用myisamchk來解壓縮。
已壓縮表有下列特徵:

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

·每個記錄是被單獨壓縮的,所以只有非常小的訪問開支。依據表中最大的記錄,一個記錄的頭在每個表中佔據1到3個位元組。每個列被不同地壓縮。通常每個列有一個不同的Huffman樹。一些壓縮型別如下:
o 字尾空間壓縮。
- 字首空間壓縮。
- 零值的數用一個位來儲存。
- 如果在一個整型列中的值有一個小的範圍,列被用最小可能的型別來儲存。比如,一個BIGINT列(8位元組),如果所有它的值在-128到127範圍內,它可以被儲存為TINYINT列(1位元組)
-如果一個列僅有一小組可能的值,列的型別被轉化成ENUM。
-一個列可以使用先前壓縮型別的任意合併。
·可以處理固定長度或動態長度記錄。

4. MyISAM表方面的問題
1. 損壞的MyISAM表
2. 未被適當關閉的表的問題

MySQL用來儲存資料的檔案格式已經被廣泛測試過,但總是有導致資料表變得損壞的環境。

1. 損壞的MyISAM表
即使MyISAM表格式非常可靠(SQL語句對錶做的所有改變在語句返回之前被寫下),如果下列任何事件發生,你依然可以獲得損壞的表:
·mysqld程式在寫中間被殺掉。
·發生未預期的計算機關閉(例如,計算機被關閉)。
·硬體故障。
·你可以同時在正被伺服器修改的表上使用外部程式(如myisamchk)。
·MySQL或MyISAM程式碼的軟體缺陷。
一個損壞的表的典型症狀如下:
·當在從表中選擇資料之時,你得到如下錯誤:
·Incorrect key file for table: '...'. Try to repair it
·查詢不能在表中找到行或返回不完全的資料。
  你可以用CHECK TABLE statement語句來檢查MyISAM表的健康,並用REPAIR TABLE修復一個損壞的MyISAM表。當mysqld不執行之時,也可以用myisamchk命令檢查或修理一個表。

如果你的表變得頻繁損壞,你應該試著確定為什麼會這樣的原因。要明白的最重要的事是表變得損壞是不是因為伺服器崩潰的結果。你可以在錯誤日誌中查詢最近的restarted mysqld訊息來早期驗證這個。如果存在這樣一個訊息,則表損壞是伺服器死掉的一個結果是很有可能的。否則,損壞可能在正常操作中發生。

2. 未被適當關閉的表的問題
每個MyISAM索引檔案(.MYI)在頭有一個計數器,它可以被用來檢查一個表是否被恰當地關閉。如果你從CHECK TABLE或myisamchk得到下列警告,意味著這個計數器已經不同步了:
clients are using or haven't closed the table properly
這個警告並不是完全意味著表已被破壞,但你至少應該檢查表。

計數器的工作方式如下:
·表在MySQL中第一次被更新,索引檔案頭的計數器加一。
·在未來的更新中,計數器不被改變。
·當表的最後例項被關閉(因為一個操作FLUSH TABLE或因為在表緩衝區中沒有空間)之時,若表已經在任何點被更新,則計數器減一。
·當你修理或檢查表並且發現表完好之時,計數器被重置為零。
·要避免與其它可能檢查表的程式進行事務的問題,若計數器為零,在關閉時計數器不減一。
換句話來說,計數器只有在下列情況會不同步:
·MyISAM表不隨第一次發出的LOCK TABLES和FLUSH TABLES被複制。
·MySQL在一次更新和最後關閉之間崩潰(注意,表可能依然完好,因為MySQL總是在每個語句之間為每件事發出寫操作)。
·一個表被myisamchk --recover或myisamchk --update-state修改,同時被mysqld使用。
·多個mysqld伺服器正使用表,並且一個伺服器在一個表上執行REPAIR TABLE或CHECK TABLE,同時該表也被另一個伺服器使用。在這個結構中,使用CHECK TABLE是安全的,雖然你可能從其它伺服器上得到警告。儘管如此,REPAIR TABLE應該被避免,因為當一個伺服器用一個新的資料檔案替代舊的之時,這並沒有傳送訊號到其它伺服器上。 總的來說,在多伺服器之間分享一個資料目錄是一個壞主意。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22664653/viewspace-683342/,如需轉載,請註明出處,否則將追究法律責任。

相關文章