char與varchar
🍓char:固定長度的字符類型。varchar屬於可變的字符類型。(那我們究竟選哪個,記住選擇varchar沒毛病!!!)
🍓為什么選擇varchar,總結為三點
- char處理速度快,但檢索時char列時,會刪除尾部的的空格,部分數據丟失的風險我們不想承擔。
- MySQL5.5后我們默認存儲引擎為InnoDB,它對長度是否固定沒有區分。主要性能取決於數據行的存儲量,我們的可變長度的存儲空間肯定是最小的。
- varchar隨着MySQL版本的不斷升性能不斷提升,除非程序對查詢速度要求很高,或字段長度變化不大可以考慮char.
char與varchar的區別如下
在MySQL中,不同的存儲引擎對CHAR和VARCHAR的使用原則有所不同,這里簡單概括如下。
MyISAM存儲引擎:建議使用固定長度的數據列代替可變長度的數據列。
MEMORY 存儲引擎:目前都使用固定長度的數據行存儲,因此無論使用 CHAR 或VARCHAR列都沒有關系。兩者都是作為CHAR類型處理。
InnoDB存儲引擎:建議使用VARCHAR類型。對於InnoDB數據表,內部的行存儲格式沒有區分固定長度和可變長度列(所有數據行都使用指向數據列值的頭指針),因此在本質上,使用固定長度的CHAR列不一定比使用可變長度VARCHAR列性能要好。因而,主要的性能因素是數據行使用的存儲總量。由於CHAR平均占用的空間多於VARCHAR,因此使用VARCHAR來最小化需要處理的數據行的存儲總量和磁盤I/O是比較好的。
text與blob
🍓保存少量字符串時,我們會選擇char或者varchar.在保存較大文本時,通常選擇使用text或者blob。
🍓text與blob的區別
- blob可以保存二進制數據,比如照片,text只能保存字符數據,如一篇文章或者日志。
🍓text和blob執行大量刪除操作后,在數據表中留下大量“空洞”。為提高性能我們可定期使用optimize table功能對這類表進行碎片整理。
演示如下
我們查看表的物理大小
這里數據文件顯示為351.89MB。從表t1中刪除id為“1”的數據
再查看表的大小
可以發現,表t1的數據文件仍然為351.89MB,並沒有因為數據刪除而減少。接下來對表進行OPTIMIZE(優化)操作:
這里mysql給的提示是Note>> Table does not support optimize, doing recreate + analyze instead
Status>> OK
也就是說 optimize table 對於innodb來說,無法作為
a single operation.以上無效。MySQL5.7已經推薦對於InnoDB的table使用 alter table table_name engine=innodb;語句的方式來進行表碎片優化。
finish!
🍓可以使用合成的(Synthetic)索引來提高大文本字段(BLOB或TEXT)的查詢性能。要注意這種技術只能用於精確匹配的查詢.
🍓在不必要的時候避免檢索大型的BLOB或TEXT值。
例如,SELECT *查詢就不是很好的想法,除非能夠確定作為約束條件的WHERE子句只會找到所需要的數據行。否則,很可能毫無目的地在網絡上傳輸大量的值。這也是 BLOB 或TEXT標識符信息存儲在合成的索引列中對用戶有所幫助的例子。用戶可以搜索索引列,決定需要的哪些數據行,然后從符合條件的數據行中檢索BLOB或TEXT值。
🍓
把BLOB或TEXT列分離到單獨的表中。
在某些環境中,如果把這些數據列移動到第二張數據表中,可以把原數據表中的數據列轉換為固定長度的數據行格式,那么它就是有意義的。這會減少主表中的碎片,可以得到固定長度數據行的性能優勢。它還可以使主數據表在運行 SELECT *查詢的時候不會通過網絡傳輸大量的BLOB或TEXT值。
浮點數與定點數
🍓
浮點數(float,double)定點數(decimal,numberic)
🍓定點數不同於浮點數,定點數實際上是以字符串形式存放的,所以定點數可以更精確的保存數據。
🍓
浮點數的精度問題。
在選擇浮點型數據保存小數時,要注意四舍五入的問題,並盡量保留足夠的小數位,避免存儲的數據不准確。
點數的比較也是一個普遍存在的問題,下面的程序片斷中對兩個浮點數做減法運算:
public class Test { public static void main(String[] args) throws Exception { System.out.print("7.22-7.0=" + (7.22f-7.0f)); } }
對上面Java程序的輸出結果可能會想當然地認為是0.22,但是,實際結果卻是7.22-7.0=0.21999979,因此,在編程中應盡量避免浮點數的比較,如果非要使用浮點數的比較則最好使用范圍比較而不要使用“==”比較。
下面使用定點數來實現上面的例子
注意:在今后關於浮點數和定點數的應用中,用戶要考慮到以下幾個原則:
浮點數存在誤差問題;
對貨幣等對精度敏感的數據,應該用定點數表示或存儲;
在編程中,如果用到浮點數,要特別注意誤差問題,並盡量避免做浮點數比較;
要注意浮點數中一些特殊值的處理。
日期類型的選擇
🍓日期類型包括:DATE \TIME\TIMESTAMP\DETATIME.
🍓
根據實際需要選擇滿足應用最小的存儲的日期類型。
如果應用只需要記錄“年份”,那么用1個字節來存儲的YEAR類型完全可以滿足,而不需要用4個字節來存儲的DATE類型。這樣不僅僅能節約存儲,更能夠提高表的操作效率。
如果要記錄年月日時分秒,並且記錄的年份比較久遠,那么最好使用 DATETIME,而不要使用TIMESTAMP。因為TIMESTAMP表示的日期范圍比DATETIME要短得多。
-
如果記錄的日期需要讓不同時區的用戶使用,那么最好使用TIMESTAMP,因為日期類型中只有它能夠和實際時區相對應。
小結
對於字符類型,要根據存儲引擎來進行相應的選擇。
對精度要求較高的應用中,建議使用定點數來存儲數值,以保證結果的准確性。
對含有 TEXT 和 BLOB 字段的表,如果經常做刪除和修改記錄的操作要定時執行OPTIMIZE TABLE功能對表進行碎片整理。
日期類型要根據實際需要選擇能夠滿足應用的最小存儲的日期類型。