MySQL作為關(guān)系型數(shù)據(jù)庫(kù),被用來(lái)存儲(chǔ)持久化的數(shù)據(jù),避免不了需要?jiǎng)?chuàng)建表。如果沒(méi)有利用ORM(對(duì)象關(guān)系模型)來(lái)自動(dòng)創(chuàng)建表,則需要開(kāi)發(fā)者通過(guò)圖形界面(Navicat)或者手寫(xiě)MySQL語(yǔ)句。
由于在生產(chǎn)環(huán)境下,我們對(duì)MySQL數(shù)據(jù)庫(kù)的操作通常是通過(guò)命令行進(jìn)行操作,因此,建議建表的時(shí)候也手寫(xiě)MySQL語(yǔ)句(不建議用圖形界面建表)。
1、添加注釋的格式
在編寫(xiě)MySQL語(yǔ)句時(shí),我們通常會(huì)被要求加上注釋,推薦的注釋格式為:

理由:這種注釋格式MySQL解析器也會(huì)認(rèn)為是注釋的,然后,會(huì)正確執(zhí)行你的create table相關(guān)語(yǔ)句。我們通常將要更改的sql語(yǔ)句整理到一個(gè)1.0.0.sql文件中,然后,你只需要登錄MySQL客戶端,輸入:source /文件目錄/1.0.0.sql。因此,這樣的注釋可以達(dá)到一舉兩得的目的。
2、指定表的引擎和缺省的編碼格式以及該表的說(shuō)明
示例語(yǔ)句如下:

理由:上述顯示的指定使用的引擎為innodb,在5.6之前默認(rèn)的引擎是MyISAM,而現(xiàn)在主流推薦性能較好的是innodb,具體參考:高性能MySQL 這本書(shū)。上述也指定了缺省字符集為utf8,還有不要漏掉使用comment來(lái)注釋下這張表的用途,便于其他開(kāi)發(fā)人員了解這張表的意圖。
3、一個(gè)經(jīng)典的建表語(yǔ)句示例并分析
示例語(yǔ)句如下:

需要注意的點(diǎn)如下:
1)所有的字段要加commet注釋
由于我們創(chuàng)建的表也可能被其他人所用,因此加上comment注釋,其他人或者我們自己可以通過(guò)命令show create tabletb_example來(lái)查看表的結(jié)果信息。
2)、int 符號(hào)確定
如果確定整形為非負(fù)數(shù),就將int設(shè)置為無(wú)符號(hào)型的,即int unsigned,可以多一半的值范圍,又能避免插入負(fù)數(shù)。int設(shè)置為無(wú)符號(hào)的場(chǎng)景在很多場(chǎng)合都使用。
3)、不定長(zhǎng)varchar的長(zhǎng)度設(shè)置
對(duì)于不定長(zhǎng)字符串varchar如果不確定字符串長(zhǎng)度(且知道字符串長(zhǎng)度小于255)可以設(shè)置為vachar(255),此時(shí),存儲(chǔ)空間只比正常的多一個(gè)字節(jié)(與設(shè)置varcahr(10)額外存儲(chǔ)的空間是一樣的),又能夠最大限度的利用varchar的特定。注意:超過(guò)255則用于存儲(chǔ)該長(zhǎng)度的空間會(huì)多于一個(gè)字節(jié)。具體參考:高性能MySQL。
4)、有限狀態(tài)的類型設(shè)置
對(duì)于表示狀態(tài)數(shù)值的數(shù)據(jù)類型建議設(shè)置為tinyint unsigned(只占用一個(gè)字節(jié)的空間) 可以表示0到255的范圍。注意:無(wú)需用int,占用四個(gè)字節(jié)的空間。
5)字段創(chuàng)建時(shí)間ctime和修改時(shí)間mtime
每個(gè)表中盡量加上字段創(chuàng)建時(shí)間ctime和字段修改時(shí)間mtime,便于后期排查問(wèn)題,知道該條記錄是何時(shí)插入,何時(shí)修改。
6)、日期時(shí)間設(shè)置為int時(shí)的查詢
這里的ctime表示創(chuàng)建時(shí)間,用的是unix時(shí)間戳來(lái)存儲(chǔ),但是不能設(shè)置缺省值unix_timestamp(),我們?cè)趯?shí)際查詢的時(shí)候,可以使用from_unixtime(ctime)來(lái)將unix時(shí)間戳轉(zhuǎn)為date日期格式。
示例如下:

效果如下:

7)所有的字段盡量設(shè)置為not null。
8)盡可能的設(shè)置default的值
比如:app_name 中通過(guò)設(shè)置default ‘’,click_cnt設(shè)置default ‘0’。
9)將有可能要進(jìn)行查詢的字段設(shè)置為索引
比如:key idx_date(“date”),這里因?yàn)榭赡軙?huì)查詢一段時(shí)間內(nèi)的數(shù)據(jù),因此添加字段“date”的索引。注意:一般索引的命名規(guī)則是idx_字段名
10)設(shè)置唯一索引
根據(jù)業(yè)務(wù)確定哪些字段或者字段組合的值是唯一的,則將該字段或字段組合設(shè)置為唯一索引。
比如:unique keyunique_date_appid(“date”, “app_id”) 這里因?yàn)楦鶕?jù)業(yè)務(wù)我們只要對(duì)于具體的某一天具體的某個(gè)應(yīng)用的記錄一定只能有一條,因此,設(shè)置聯(lián)合唯一索引可以防止改天對(duì)應(yīng)的該應(yīng)用的數(shù)據(jù)重復(fù)插入。注意:唯一索引的命名規(guī)則為:unique_字段1_字段2。
11)SQL PRIMARY KEY 約束
PRIMARY KEY 約束唯一標(biāo)識(shí)數(shù)據(jù)庫(kù)表中的每條記錄。
主鍵必須包含唯一的值。
主鍵列不能包含 NULL 值。
每個(gè)表都應(yīng)該有一個(gè)主鍵,并且每個(gè)表只能有一個(gè)主鍵。
一個(gè)小知識(shí)點(diǎn):
由于我們添加了唯一索引unique_date_appid,如果插入重復(fù)的date 和 app_id組合,則會(huì)報(bào)聯(lián)合索引重復(fù)錯(cuò)誤,比如,再次執(zhí)行:

提示:

我們可以通過(guò)返回結(jié)果result進(jìn)行判斷,如果result為0,則表示重復(fù)插入。