從存儲上講:
-
- text 是要要進 overflow存儲。 也是對於text字段,不會和行數據存在一起。但原則上不會全部overflow ,
-
會有768字節和原始的行存儲在一塊,多於768的行會存在和行相同的Page或是其它Page上。
-
-
- varchar 在MySQL內部屬於從blob發展出來的一個結構,在早期版本中innobase中,也是768字節以后進行overfolw存儲。
-
-
- 對於Innodb-plugin后: 對於變長字段處理都是20Byte后進行 overflow存儲
-
(在新的row_format下:dynimic compress)
說完存儲后,說一下使用這些大的變長字段的缺點:
-
- 在Innobase中,變長字段,是盡可能的存儲到一個Page里,這樣,如果使用到這些大的變長字段,會造成一個Page里能容納的行
-
數很少,在查詢時,雖然沒查詢這些大的字段,但也會加載到innodb buffer pool中,等於浪費的內存。
-
(buffer pool 的緩存是按page為單位)(不在一個page了會增加隨機的IO)
-
-
- 在innodb-plugin中為了減少這種大的變長字段對內存的浪費,引入了大於20個字節的,都進行overflow存儲,
-
而且希望不要存到相同的page中,為了增加一個page里能存儲更多的行,提高buffer pool的利用率。 這也要求我們,
-
如果不是特別需要就不要讀取那些變長的字段。
那問題來了? 為什么varchar(255+)存儲上和text很相似了,但為什么還要有varchar, mediumtext, text這些類型?
(從存儲上來講大於255的varchar可以說是轉換成了text.這也是為什么varchar大於65535了會轉成mediumtext)
我理解:這塊是一方面的兼容,另一方面在非空的默認值上varchar和text有區別。從整體上看功能上還是差別的。
這里還涉及到字段額外開銷的:
-
- varchar 小於 255byte 1byte overhead
-
- varchar 大於 255byte 2byte overhead
-
-
- tinytext 0-255 1 byte overhead
-
- text 0-65535 byte 2 byte overhead
-
- mediumtext 0-16M 3 byte overhead
-
-
- longtext 0-4Gb 4byte overhead
備注 overhead是指需要幾個字節用於記錄該字段的實際長度。
從處理形態上來講varchar 大於768字節后,實質上存儲和text差別不是太大了。 基本認為是一樣的。
另外從8000byte這個點說明一下: 對於varcahr, text如果行不超過8000byte(大約的數,innodb data page的一半) ,overflow不會存到別的page中。基於上面的特性可以總結為text只是一個MySQL擴展出來的特殊語法有兼容的感覺。
默認值問題:
-
- 對於text字段,MySQL不允許有默認值。
-
- varchar允許有默認值
總結:
-
根據存儲的實現: 可以考慮用 varchar替代tinytext
-
如果需要非空的默認值,就必須使用 varchar
-
如果存儲的數據大於 64K,就必須使用到mediumtext , longtext
-
varchar(255+)和text在存儲機制是一樣的
-
-
需要特別注意 varchar(255)不只是255byte ,實質上有可能占用的更多。
-
-
特別注意, varchar大字段一樣的會降低性能,所以在設計中還是一個原則大字段要拆出去,主表還是要盡量的瘦小