MySQL表設計有一些比較重要的點,面試的時候常常會被問到。
為什么一定要設置一個主鍵?
在不設置主鍵的情況下,InnoDB存儲引擎會幫你生成一個隱藏列作為自增主鍵。因此,手動指定主鍵可以為以后的維護帶來便利,比如說在自定義主鍵上建立主鍵索引來提高查詢效率。
主鍵是用自增還是隨機(UUID)?
主鍵建議是自增的好。因為InnoDB中的主鍵是聚簇索引,如果主鍵是自增的話,每次插入新的記錄就會順序添加到當前索引節點的后續位置,當一頁寫滿就會自動開辟新的頁。如果不是自增主鍵,可能就會在中間插入,引發頁的分裂導致產生很多表空間的碎片。
可以理解為當主鍵是UUID的時候,插入表記錄的時間會更長,占用空間也會更大。
主鍵為什么不推薦有業務含義?
主要有兩點。
1.任何有業務含義的列都有改變的可能性,主鍵一旦帶上了業務含義,那么主鍵就有可能發生變更。而主鍵一旦發生變更,該記錄數據在磁盤上的存儲位置就會發生改變,甚至有可能會引發頁分裂導致產生空間碎片。
2.帶有業務含義的主鍵就不一定是順序自增的了,這樣就會導致數據的插入順序不到有序的,也不能保證后面插入數據的主鍵一定比前面的數據大。如果出現了后面插入數據的主鍵比前面的小的情況,就有可能引發頁分裂導致產生空間碎片。
表示枚舉的字段為什么不用enum類型?
表示枚舉的字段一般選用tinyint類型。不選用enum類型主要有兩個原因:
1.enum類型的order by的操作效率低,需要額外的操作。
2.如果枚舉值是數值類型的,會很容易出現語法陷阱,枚舉的下標和數值很容易會被弄混淆。
貨幣字段用什么類型?
如果貨幣單位是分,可以是int類型;如果堅持用元,則要用decimal類型。
但是是不能用float和double類型的,因為這兩個類型是以二進制存儲的,會有一定的誤差。比如float類型如果你insert一個1234567.23,查詢出來的結果可能是1234567.25。
時間字段用什么類型?
時間字段的話需要結合項目背景,varchar、timestamp、datetime或bigint類型都可以。
1.varchar類型。如果用varchar類型來存時間,優點在於顯示直觀,存取都方便。但是缺點也是挺多的,比如插入的數據沒有校驗,某一天你可能會發現數據庫中存了一個2019-06-31的數據。其次,做時間比較運算時需要用str_to_date()
等函數將其轉化為時間類型,除非建立基於函數的索引,否則這么寫是無法命中索引的,數據量一大,查詢效率就會很低。
2.timestamp類型。這個類型是四個字節的整數,它能表示的時間范圍為1970-01-01 08:00:01到2038-01-19 11:14:07,而2038年以后的時間,是無法用timestamp類型存儲的。但是它有一個優勢是它帶有時區信息的,一旦系統中的時區發生改變,項目中的該字段的值也會自己發生改變。
3.datetime類型。datetime類型的儲存占用8個字節,存儲的時間范圍為1000-01-01 00:00:00 ~ 9999-12-31 23:59:59。顯然,存儲時間范圍更大,但是它存儲的是時間絕對值,不帶有時區信息。如果改變了數據庫的時區,該項的值不會自己發生變更。
4.bigint類型。這個類型也是8個字節,自己維護一個時間戳,表示范圍比timestamp類型大多了。缺點就是要自己維護,不大方便。
為什么不直接存儲圖片、音頻和視頻等大容量內容?
在實際應用中,一般都是用HDFS來存儲文件的,在MySQL中只會存文件的存放路徑。但是實際上MySQL是有提供兩個字段類型被涉及用來存放大容量文件的,一個是text類型,一個是blob類型。然而在生產中基本不會使用這兩個類型,主要原因如下:
1.MySQL內存臨時表不支持text和blob這樣的大數據類型。如果查詢中包含這樣的數據,那么在排序等操作的時候就不能夠使用內存臨時表,只能使用磁盤臨時表,會導致查詢效率低下。
2.這兩種類型會造成binlog的內容太多。因為數據的內容比較大,也就會造成binlog的內容比較多。我們知道,主從同步是通過binlog來進行的,如果binlog過大,就會導致主從同步的效率問題。
為什么字段要被定義為NOT NULL?
1.索引的性能不好。MySQL難以優化引用可空列查詢,它會使得索引、索引統計和值更加復雜。可空列需要更多的存儲空間,還需要MySQL內部進行特殊處理。可空列被索引后,每條記錄都需要一個額外的字節。
2.查詢可能會出現一些不可預料的結果。比如說使用count()聚合函數去統計一個可為空的字段,那么最后統計出來的記錄數可能會和實際的記錄數不同。
MySQL表設計面試題的總結
MySQL如果要深入提問的話,可以把你問到叫爸爸,因此平時要注意多積累。
另外要注意的是,上面的回答都是基於InnoDB存儲引擎的。
"心結如果真的打不開,你就給它系成個花樣兒,其實生活就需要這樣。"