數(shù)據(jù)庫設(shè)計
前要:字符串長度不是定義字節(jié)數(shù),而是字符數(shù)友酱,多字節(jié)字符集需要更多的空間存儲單個字符晴音。
字段設(shè)計維度的思考
可以按照以下維度考慮設(shè)計:
- 按照字段的使用頻率設(shè)計,預(yù)判性的分為冷缔杉、溫段多、熱字段設(shè)計表
- 根據(jù)展示數(shù)據(jù)展示位置來設(shè)計,比如有些數(shù)據(jù)只在個人中心顯示而不會在其他地方顯示
- 根據(jù)字段的大小設(shè)計表壮吩,比如进苍,有些大文本 text加缘,blob的類型的可以考慮拆分。
- 按照讀/寫(更新)的比例來設(shè)計表
數(shù)據(jù)類型的選擇
- 更小的通常更快觉啊,性能更佳原因在于占用更少的磁盤拣宏,內(nèi)存,cpu緩存并且需要處理的cpu周期也更小杠人。但是要確認你沒有低估存儲值的范圍
- 盡量避免NULL勋乾,相對于mysql來說,他更難優(yōu)化嗡善,因為NULL的列使得索引辑莫、索引統(tǒng)計和值比較都更為復(fù)雜。
- 在mysql中罩引,整型的計算一般使用bigint(64位)來計算各吨,即使是32位的環(huán)境也是如此。但是一些聚合函數(shù)例外袁铐,他們使用decimal和double來計算
- decimal類型通常用來存儲精確小數(shù)揭蜒,因為他支持高精確計算(5.0及其以后)
索引的建立
- 盡量避免在可為NULL的列上創(chuàng)建索引
- 等
應(yīng)該使用整型來存儲IP地址?
通常情況下剔桨,人們使用varchar(15)來存儲IPv4的地址屉更,事實上,他們是32位的無符號整型洒缀,而不是字符串瑰谜,用小數(shù)點分割成四部分只是為了讓人們簡單易懂,所以應(yīng)該用無符號整型來存儲ip地址树绩,mysql同時也提供了INET_ATON()和INET_NTOA()函數(shù)在這兩者之間轉(zhuǎn)換似舵。
如何在數(shù)據(jù)庫中存儲錢?
將需要存儲的貨幣單位更加小數(shù)的位數(shù)乘以相應(yīng)的倍數(shù)即可葱峡,假設(shè),我們要存儲到萬分之一分龙助,那么我們就把所有的金額乘以一百萬砰奕,將結(jié)果存儲在bigint中,這樣就可以避免浮點存儲計算不精確和decimal精確計算代價高的問題提鸟。
數(shù)據(jù)庫中DATETIME和TIMESAMP的區(qū)別军援?
他們都可以存儲相同的數(shù)據(jù)類型:時間和日期,精確到秒称勋。
但是區(qū)別:
- TIMESAMP只使用DATETIME一半的存儲空間胸哥,并且會根據(jù)時區(qū)變化,具有特殊的自動更新能力赡鲜。
- TIMESAMP允許的時間范圍要小很多空厌,所以有時候他上面的特殊能力可能為成為他的障礙庐船。
- TIMESAMP能表示從1970年1月1日午夜以來的秒數(shù)到2038年,而DATETIME能保存1001年到9999年,精度為秒嘲更。
在數(shù)據(jù)庫中如何保存到微秒級別的時間戳筐钟?
答案是:使用bigint類型存儲微秒級別的時間戳也可以切換到mariadb來代替mysql
varchar和char的區(qū)別?
varchar:
varchar類型存儲的是可變長的字符串赋朦,他比定長類型的更節(jié)省空間篓冲,因為他只用必要的空間,字符越短使用越少的空間宠哄,但是有一種情況例外壹将,就是使用ROW_FORMAT=FIXED創(chuàng)建的話,每一行都使用的定長存儲毛嫉,這很浪費空間诽俯,另外varchar需要一到兩個字節(jié)額外記錄字符串的長度,如果列小于255個字節(jié)狱庇,那么使用一個字節(jié)惊畏,否則使用兩個。假設(shè)使用latin1字符集密任,則一個varchar(10)的列需要11個字節(jié)的存儲空間颜启,而varchar(20000)需要20002個字節(jié),因為需要存儲長度信息浪讳。
varchar雖然節(jié)省了空間缰盏,對性能有幫助,但由于是變長的淹遵,在update時可能會讓行比原來更長口猜,那么這就有額外的工作,這個行占用的空間增長透揣,并且在此頁內(nèi)沒有更多的空間存儲济炎,這種情況下,不同的存儲引擎的處理方式不一樣辐真,比如:myisam將拆成不同的片段存儲须尚,innodb則需要分裂頁使得行可以放在列內(nèi),總之侍咱,就是加重了碎片化耐床。
char:
char是定長的,mysql會根據(jù)定義的字符串長度來分配足夠的空間楔脯,當(dāng)存儲char的時候撩轰,mysql會刪除末尾的空格,且char值會根據(jù)采用空格進行填充
總結(jié):
varchar適合
- 字符串列的最大長度比平均長度大很多,列更新很少的情況堪嫂,這樣碎片化不是問題偎箫,就像使用utf-8這樣復(fù)雜的字符集,每個字符度使用不同的字節(jié)數(shù)進行存儲溉苛。
- 注意:innodb會把過長的varchar處理成blob
char適合
- 存儲很短的字符串或者所有的值接近同一個長度镜廉,例如char比較適合存儲密碼md5值,因為這是一個定長的值愚战。
- 對于經(jīng)常變更的數(shù)據(jù)娇唯,char也比varchar更好,因為定長的不容易產(chǎn)生碎片寂玲。
- 對于非常短的列塔插,char比varchar在存儲空間上更有效率,因為varchar會需要額外字節(jié)來記錄長度拓哟。
個人博客:yulibaozi.com