SQL優化系列 - MySQL表設計時要注意什麼?

前言

今天是5月的最後一天了,一邊聽着五月天的線上演唱會,一邊整理下學過SQL相關的內容,之前有篇是針對SQL的知識點:https://blog.csdn.net/Totoro1745/article/details/106036161,接下來的優化系列也會不斷的進行更新~

MySQL表設計時要注意什麼?

1.爲什麼一定要設一個主鍵?
在不設主鍵的情況下,innodb也會生成一個隱藏列,作爲自增主鍵。自己指定一個主鍵,在有些情況下,就能顯式的用上主鍵索引,提高查詢效率~

2.主鍵爲什麼最好用自增呢?
innodb 中的主鍵是聚簇索引。如果主鍵是自增的,那麼每次插入新的記錄,記錄就會順序添加到當前索引節點的後續位置,當一頁寫滿,就會自動開闢一個新的頁。如果不是自增主鍵,那麼可能會在中間插入,就會引發頁的分裂,從而產生很多表碎片,所以用自增插入性能好~

3.主鍵爲什麼不推薦有業務含義呢?
主要有以下兩個原因:
(1)因爲任何有業務含義的列都有改變的可能性,主鍵一旦帶上了業務含義,那麼主鍵就有可能發生變更。主鍵一旦發生變更,該數據在磁盤上的存儲位置就會發生變更,有可能會引發頁分裂,產生空間碎片。
(2)帶有業務含義的主鍵,不一定是順序自增的。那麼就會導致數據的插入順序,並不能保證後面插入數據的主鍵一定比前面的數據大。如果出現了,後面插入數據的主鍵比前面的小,就有可能引發頁分裂,產生空間碎片。

4.表示枚舉的字段爲什麼不用enum類型?
在工作中表示枚舉的字段,一般用tinyint類型。
不用enum類型有兩個原因:
(1)ENUM類型的ORDER BY操作效率低,需要額外操作
(2)如果枚舉值是數值,有陷阱

5.貨幣字段用什麼類型?
如果貨幣單位是分,可以用Int類型。如果堅持用元,用Decimal。
最好不要用float和double,因爲float和double是以二進制存儲的,所以有一定的誤差,對於錢的東西要慎重!

6.時間字段用什麼類型?
(1)varchar,如果用varchar類型來存時間,優點在於顯示直觀,但是坑的地方也是挺多的。比如,插入的數據沒有校驗,你可能某天就發現一條數據爲2013111的數據,請問這是代表2013年1月11日,還是2013年11月1日?其次,做時間比較運算,你需要用STR_TO_DATE等函數將其轉化爲時間類型,你會發現這麼寫是無法命中索引的。數據量一大,是個坑!
(2)timestamp,該類型是四個字節的整數,它能表示的時間範圍爲1970-01-01 08:00:01到2038-01-19 11:14:07。2038年以後的時間,是無法用timestamp類型存儲的。但是它有一個優勢,timestamp類型是帶有時區信息的。一旦你係統中的時區發生改變,例如你修改了時區SET TIME_ZONE = “america/new_york”;你會發現,項目中的該字段的值自己會發生變更。這個特性用來做一些國際化大項目,跨時區的應用時,特別注意!
(3)datetime,datetime儲存佔用8個字節,它存儲的時間範圍爲1000-01-01 00:00:00 ~ 9999-12-31 23:59:59。顯然,存儲時間範圍更大。但是它坑的地方在於,他存儲的是時間絕對值,不帶有時區信息。如果你改變數據庫的時區,該項的值不會自己發生變更!
(4)bigint,也是8個字節,自己維護一個時間戳,表示範圍比timestamp大多了,就是要自己維護,不大方便。

7.爲什麼不直接存儲圖片、音頻、視頻等大容量內容?
mysql中有兩個字段類型被用來設計存放大容量文件,也就是text和blob類型。但是,我們在生產中,基本不用這兩個類型~Mysql內存臨時表不支持TEXT、BLOB這樣的大數據類型,如果查詢中包含這樣的數據,在排序等操作時,就不能使用內存臨時表,必須使用磁盤臨時表進行。導致查詢效率緩慢。

8.字段爲什麼要定義爲NOT NULL?
(1)索引性能不好
(2)查詢會出現一些不可預料的結果(空值不會被計算)

參考資料:https://mp.weixin.qq.com/s/HPODDzEVofXwU9IOvi9dhw

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章