建表原則
- 定長與變長分離
如id int,佔4個位元組,char(4)佔4個字元長度,也是定長,time
即每個單元值佔的位元組是固定的。
核心且常用欄位宜建成定長放在一張表,而varchar,text,blob這種變長欄位適合單放一張表,用主鍵與核心表關聯起來
- 常用欄位與不常用欄位要分離
需結合網站的具體業務來分析,分析欄位的查詢場景,查詢頻率低的欄位單獨拆出來
- 在一對多需要關聯統計的欄位上新增冗餘欄位
如select count(b.*) from a left join b on a.id=b.aid where a.id=1
這種查詢宜在a表直接建立統計欄位,有新增就加一,而不是通過關聯查詢
列選擇原則
- 欄位型別優先順序
整形 > date、time > enum、char > varchar > blob、text
列的特點分析:
整形:定長,沒有國家/地區之分,沒有字符集的差異
比如tinyint 1,2,3,4,5和char(1) 1,2,3,4,5,從空間上都是佔1位元組,但order by前者更快,因為後者要考慮字符集(如utf8)與校對集(就是排序規則)
time:定長、運算快、節省空間;考慮時區,寫sql不方便
enum:列舉型別,內部用整型來儲存,能起到約束值的目的。但與char聯查時,內部要經歷串與值的轉化
char:定長,考慮字符集和校對集
varchar:不定長,要考慮字符集的轉換和排序時的校對集,速度慢
text/blob:無法使用記憶體臨時表(排序等操作只能在磁碟上進行)
- 夠用就行,不要慷慨
大的欄位浪費記憶體,影響速度;以年齡為例tinyint unsigned not null
,可以儲存255歲,用int的話就浪費了3個位元組;又比如varvhar(10)
和varvhar(255)
儲存相同內容,看似varchar因為變長佔用相同,但在表聯查時varvhar(255)要花更多記憶體
- 儘量不實用null
原因:null不利於索引,要用特殊的位元組來標註,在磁碟上佔據的空間其實更大