表設計原則
mysql存儲原理
記錄存儲方式
- 記錄按行存儲在頁內
- 按照主鍵順序
- 頁內單向鏈表
- 頁間雙向鏈表
基本數據類型
tinyint,smallint,mediumint,int,bigint,
float, double,decimal(存儲類型,cup不支持直接計算)
varchar,char
MySQL的數據類型中長度的含義
- 字節:8位=1個字節
- 字符:gbk編碼中一個字符佔2個字節,utf-8編碼中一個字符佔3個字節
- 對於gbk類型,行長度最大爲65535,則varchar列的最大長度算法就是 (65535-2)/2 =32766.5,所以此處就是32766了。
- 對於utf8還是有很大的差別,對應的是3個字節,所以需要除以3,按照(65535-2)/3,最大值就是21844了。
- char(n)和varchar(n)中的n代表字符的長度
- 整數類型的字段長度已經被系統固定死,所以int(n)中n幾乎沒有任何使用場景,它的含義是“顯示位寬”,這個n無論填任何數,不影響存儲環節,僅影響在檢索時的輸出格式
這5種整型的佔用空間分別是:
序號 | 類型 | 長度 | 範圍(無符號) | 範圍有符號 |
---|---|---|---|---|
1 | tinyint | 1個字節 | 0 ~ 2^8 -1 | -2^8 ~ 2^8-1 |
2 | smallint | 2個字節 | 0 ~ 2^(8x2)-1 | -2^(8x2) ~ 2^(8x2)-1 |
3 | mediumint | 3個字節 | 0 ~ 2^(8x3)-1 | -2^(8x3) ~ 2^(8x3)-1 |
4 | int | 4個字節 | 0 ~ 2^(8x4)-1 | -2^(8x4) ~ 2^(8x4)-1 |
5 | bigint | 8個字節 | 0 ~ 2^(8x8)-1 | -2^(8x8) ~ 2^(8x8)-1 |
索引
索引使用技巧
- 聯合索引:優於多列獨立索引
- 索引順序:選擇性高的在前面
- 覆蓋索引:二級索引存儲主鍵值更有利
- 索引排序:索引同時滿足查詢和排序
- 使用獨立列:索引不能是表達式,不能是函數的參數
- 建議多使用EXPLAIN 分析查詢
主鍵索引
InnoDB會自動在表的主鍵上創建索引,數據結構使用B+Tree,主鍵索引也稱爲聚簇索引,它的索引結構和實際數據是存儲在一起的,B+Tree葉子節點存儲的就是實際的記錄。
非主鍵索引
非主鍵索引是先通過自身索引結構找到主鍵值,然後再用主鍵值再聚簇索引上找打相應的記錄,InnoDB就是這麼做的,非主鍵索引也稱爲二級索引,特點是:
- 除了主鍵以意以外的索引
- 索引結構的葉子節點中的Data是主鍵值
- 一次查詢需要查找自身和主鍵兩個索引
聯合索引
也稱作多列索引,索引結構的key包含多個字段,排序時先按第一列比較,如果相同再按第二列比較,以此類推。聯合索引上的查詢需要滿足一下特點:
- key按照最左原則開始查找,否則無法使用索引
- 跳過中間列,會導致後面的列不能使用索引
- 某列使用範圍查找時,後面的列不能使用到索引
- 根據前綴索引特性,聯合索引(a,b,c),可以滿足(a),(a,b),(a,b,c)三種索引查詢,但是不滿足(a,c),(b,c)索引查詢
主鍵選擇
- 業務主鍵:更符合業務的查詢需求。寫入、查詢效率和磁盤利用率低,可以使用一級索引,覆蓋索引
- 自增主鍵:主鍵值傳遞,數據是順序插入的,所以在頁內數據物理連續,寫滿一頁後再順序分配下一頁,再沒有刪除操作的情況下,磁盤利用率高,且隨機IO很低,插入效率很高
- 隨機主鍵:寫入、查詢效率和磁盤利用率低,每次查詢走兩級索引
索引個數
- 由於過多的索引會造成索引文件過大,所以索引個數最好不多於五個
列(字段)類型選擇
- 通常越小、越簡單越好,例如bool字段統一用tinyint,枚舉類型也用tinyint,交易金額用long,針對金額數據,雖然InnoDB提供了支持精確計算的DECIMAL類型,但DECIMAL是存儲類型不算數據類型,不支持cup原生計算,所以將小數點後的小數經處理轉換成整數long存儲
分表策略
- 首先要明確數據庫出現性能問題一般都是在數據量到達一定的量級以後
- 提前做好預估,不要等需要拆分的時候再拆,一般把數據量控制再千萬級別
- 常用分表策略有:按key取模,按時間分,兩種,冷熱數據明確。