Mysql表設計需要注意的問題


下面探討的數據庫為MySQL 存儲引擎為innodb因為這是最常見的,使用最多的數據庫和引擎

什么是頁分裂?

這是因為聚簇索引采用的是平衡二叉樹算法,而且每個節點都保存了該主鍵所對應行的數據,假設插入數據的主鍵是自增長的,那么根據二叉樹算法會很快的把該數據添加到某個節點下,而其他的節點不用動;但是如果插入的是不規則的數據,那么每次插入都會改變二叉樹之前的數據狀態。從而導致了頁分裂。

為什么一定要設置一個主鍵

因為就算你不主動設置一個主鍵,innodb也會幫你生成一個隱藏列,作為自增主鍵來使用。所以,不管怎么樣都會有自增主鍵,還不如自己指定一個,主鍵索引可以提高查詢效率。

主鍵使用自增還是UUID

主鍵肯定是用自增。innodb種的主鍵是聚族索引,如果主鍵是自增的,那么每次插入的新數據都會順序添加到當前索引節點的后續位置,當一頁寫滿時,就會自動開啟第二頁,如果不是自增主鍵,那么就可能在中間插入,就會引發頁的分裂,產生很多碎片,總之用自增主鍵性能更好。

UUID產生的索引文件更大,當數據量超過一百萬行時,主鍵查詢性能和索引文件大小都比UUID要更有效率和更小。

 

主鍵為什么不推薦有業務含義

1)因為任何含有業務的列都有改變的可能性,主鍵一旦帶上業務含義,那么主鍵就有可能發生改變。主鍵發生改變,該數據在磁盤上的存儲位置就會發生更改,有可能引發頁分裂,產生空間碎片。

2)帶有業務含義的主鍵不一定是順序自增的,就有可能導致后邊插入的數據主鍵一定比前面的大,如果出現后邊插入的數據主鍵比前面插入的小,就肯能引發頁分裂,產生空間碎片。

 

表示枚舉的字段為什么不用enum類型

首先,枚舉在MySQL中一般用tinyint類型,為什么不使用enum呢

1)ENUM類型,order by操作效率低,需要額外的操作

2)如果枚舉是數值,有陷阱

例如:表結構如下create table test(sex enum('0','1'))此時執行插入語句insert into test values(1) 查詢的結果為0

只有這樣插入insert into test values('1')此時結果才是1

 

貨幣字段用什么類型

貨幣:如果貨幣單位是分,可以使用int類型,如果堅持用元的話,可以使用Decimal類型,不能使用float和double類型,因為這兩個類型是以二進制存儲的,所有有一定的誤差。

例如:create table 't'('price' float(10,2) default null) engine=innodb default charset=utf8然后插入一條數據price=120.23,然后你會發現數據變為120.25,精度失准。

 

時間字段用什么類型

1)如果使用varchar,優點是顯示直觀,缺點是做時間比較運算的時候,需要使用str_to_date等函數把它轉化為事件類型,你會發現這是無法命中索引的,數據量一大,這就是一個大坑。

2)如果使用timestamp類型,該類型為4個字節,表示的時間范圍為1970-01-01 到2038-01-19 也就是說2038年以后的時間不能使用timestamp存儲。該類型有一個優勢,就是自帶時區,如果修改了時區,該字段值會跟着改變。

3)dtatime類型,該類型為8個字節,自己維護一個時間戳,表示范圍比timestamp大,因為需要自己維護,所以不太方便。

 

為什么不直接存儲圖片、音頻、視頻等大容量內容

在實際生產中,我們都是在文件服務器上存真實文件,數據庫中保存對應的文件路勁即可,MySQL有存放大文件的類型,text和blob類型,但是基本不使用

1)MySQL內存臨時表不支持text、blob這樣的大數據類型,如果查詢中包含這樣的數據,在排序等操作時,就不能使用內存臨時表,必須使用磁盤臨時表,導致效率低下。

2)binlog內容太多,因為數據內容過大,會導致binlog內容較多,而MySQL主從同步靠binlog進行同步,binlog太大就會導致主從同步效率問題。

 

字段為什么要定義為NOT NULL

1)索引性能不好

2)查詢會出現一些不可預料的結果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM