Mysql 表設計
Mysql要設一張好的表, 先要了解以下2個知識:
- 數據類型
- 索引
數據類型
- 整數
- TINYINT
- 存儲空間8位
- -128 ~ 127
- 0 ~ 255
- SMALLINT
- 存儲空間16位
- -32,768 ~ 32,767
- 0 ~ 65535
- MEDIUMINT
- 存儲空間24位
- -8388608 ~ 8388607
- 0 ~ 16777215
- INT
- 存儲空間32位
- -2,147,483,648 ~ 2,147,483,647
- 0 ~ 4294967295
- BIGINT
- 存儲空間64位
- -9223372036854775808 ~ 9223372036854775807
- 0 ~ 18446744073709551615
- TINYINT
- 實數
- DOUBLE
- 8字節
- Float
- 4字節
- DECIMAL
- DECIMAL(18,9) 小數點左右各存9個數字,每個數字4字節,小數點1字節,一共9字節
- DOUBLE
- 字符串
- CHAR 定長字符串
- VARCHAR 可變長字符串
- 長度小於255時, 使用1個額外字節記錄長度信息, 大於255時使用2字節
- BLOB
- TEXT
- 枚舉ENUM
- 日期
- DATETIME
- 8字節
- 1001年 ~ 9999年
- TIMESTAMP
- 4字節
- 1970年 ~ 2038年
- DATETIME
整數 有符號與無符號的效率是一樣的, 應選擇小但夠用的類型
對於實數, 可以選擇使用整數存儲, 計算時除以10/100/1000就可以得到一個小數
字符串 長度固定的應選擇CHAR, VARCHAR可以優化存儲空間, 但UPDATE需要額外的工作, 使用VARCHAR時應分配真正需要的空間,不要多分配
BLOB&TEXT 儘量避免使用
枚舉類 可以用整數代替
TIMESTAMP的空間效率比DATETIME高
避免使用NULL, 會使得索引和值比較變得更負責
IP地址 使用無符號整數存儲 INET_ATON() & INET_NTOA()進行轉換
電話號碼 使用無符號整數存儲, 空間效率更高, 而且可以數據類型校驗
索引(B-Tree)
- B-Tree索引必須從左到右按順序匹配(個數不限,按順序就可以)纔有效
- 索引查詢間不能有範圍(<,>,like, <> …)查詢, 除IN和<=>(<>和<=>是不同的操作)
表達式&函數不能使用索引(例如:id + 1 = 5, id + 1是表達式不能使用id索引)
索引選擇 不重複的索引值 / 總值 佔比最高的
對於字符串, 可以冗餘字段存儲字符串的哈希作爲索引(CRC32(), FNV64())
索引可以用於排序, 但必須滿足索引的使用條件
IN會以指數增加, 一個查詢中的IN不能太多
- 例如: where a1 in (1,2,3) and a2 in (4,5,6,7) and a3 in (9,10) 就會有 3*4*2 = 24種不同的組合
技巧
- 不要有太多的列
- 單個查詢關聯在12表以內
- 避免NULL
- 某些冗餘字段可以提升查詢
- 緩存表 & 彙總表
- 計數器表