MySQL DB開(kāi)發(fā)規(guī)范

1 命名規(guī)范

1.1表命名

  • 實(shí)體表使用盡量準(zhǔn)確的英文單數(shù)表示,若一個(gè)英文單詞不足以表示表的意義,可用下橫杠分割,小寫(xiě)命名。(目前都是以t_開(kāi)頭,那就繼續(xù)吧)
  • 按日期時(shí)間分表須符合_YYYY[MM][DD]格式
    這也是為將來(lái)有可能分表做準(zhǔn)備的,比如t_table_name_201403。不具有時(shí)間特性的,直接以 t_tbname_001 這樣的方式命名。

1.2字段

字段命名含義明確,小寫(xiě)字母,下橫杠分割, 字段名字中不要含有表名(表已經(jīng)代表了這個(gè)實(shí)體的含義)。

1.3索引

非唯一索引命名為idx_列名1_列名2
唯一索引命名為uk_列名1_列名2
如果列名太長(zhǎng)或列太多,可酌情精簡(jiǎn)

表名、字段名,索引名支持最多64個(gè)字符,但為了統(tǒng)一規(guī)范、易于辨識(shí)以及減少傳輸量,禁止超過(guò)32個(gè)字符。

2 庫(kù)表基礎(chǔ)規(guī)范

2.1存儲(chǔ)引擎

統(tǒng)一使用Innodb存儲(chǔ)引擎
5.5版本開(kāi)始mysql默認(rèn)存儲(chǔ)引擎就是InnoDB,5.7版本開(kāi)始,系統(tǒng)表都放棄MyISAM了

2.2字符集

字符集統(tǒng)一使用UTF8。如果遇到EMOJ等表情符號(hào)的存儲(chǔ)需求,可使用UTF8MB4字符集

2.3注釋

所有表和字段都盡量需要添加注釋

2.4主鍵

所有表都必須要顯式指定主鍵
主鍵盡量采用自增方式,InnoDB表實(shí)際是一棵索引組織表,順序存儲(chǔ)可以提高存取效率,充分利用磁盤空間。并且有利于bufferpool中儲(chǔ)存更多的二級(jí)索引記錄(二級(jí)索引里包含了主鍵值)

3 字段規(guī)范

3.1字符串類型

類型 范圍(字節(jié)) char(N) 0-255 varchar(N) 0-65535 text 0-65535
注:N為字符數(shù)而不是字節(jié)數(shù),根據(jù)編碼不同占用不同的字節(jié),UTF8編碼下,一個(gè)中文字符占用3個(gè)字節(jié),GBK編碼下一個(gè)中文字符占用2個(gè)字節(jié)

  • varchar類型保存可變長(zhǎng)度字符串,范圍0-65535(但受到單行最大64kb的限制),盡量根據(jù)業(yè)務(wù)需求定義合適的字段長(zhǎng)度,不要為了圖省事,直接定義為varchar(1024)或更長(zhǎng)等等。
    eg.用varchar(30)去存放abcd,實(shí)際使用4+1=5個(gè)字節(jié),因?yàn)檫€需要使用額外1個(gè)字節(jié)來(lái)標(biāo)識(shí)字符串長(zhǎng)度(0-255使用1個(gè)字節(jié),超過(guò)255需要2個(gè)字節(jié))。

  • char類型是使用固定長(zhǎng)度空間進(jìn)行存儲(chǔ),不容易產(chǎn)生碎片,范圍0-255。
    eg.CHAR(30)能放30個(gè)字符,存放abcd時(shí),尾部會(huì)以空格補(bǔ)齊,實(shí)際占用空間 30個(gè)字節(jié) 。檢索它的時(shí)候尾部空格會(huì)被去除。

  • 對(duì)于text字段,MySQL不允許有默認(rèn)值。varchar允許有默認(rèn)值

  • varchar(768+)和text在存儲(chǔ)形態(tài)是一樣的(都是需要額外的2個(gè)字節(jié)來(lái)標(biāo)識(shí)字符串長(zhǎng)度,且都會(huì)進(jìn)行overflow存儲(chǔ))

特別注意,varchar大字段一樣的會(huì)降低性能,所以在設(shè)計(jì)中還是一個(gè)原則大字段要拆出去,主表還是要盡量的瘦

3.2 整數(shù)類型

類型 字節(jié) 最小值 最大值 (帶符號(hào)的/無(wú)符號(hào)的) (帶符號(hào)的/無(wú)符號(hào)的) TINYINT 1 -128 127 0 255 SMALLINT 2 -32768 32767 0 65535 MEDIUMINT 3 -8388608 8388607 0 16777215 INT 4 -2147483648 2147483647 0 4294967295 BIGINT 8 -9.22337E+18 9.22337E+18 0 1.84467E+19

  • 所有整數(shù)類型的字段盡量使用合適的大小??梢詾檎麛?shù)類型指定寬度(比如int(11),這種括號(hào)里的值),但大多數(shù)時(shí)候沒(méi)有意義,它不會(huì)限制值的合法范圍
  • 可以使用tinyint存儲(chǔ)狀態(tài)值。比enum減少cpu開(kāi)銷,且容易維護(hù)。
  • 建議使用 UNSIGNED 存儲(chǔ)非負(fù)數(shù)值
    相比不使用 unsigned,可以擴(kuò)大一倍使用數(shù)值范圍

3.3 實(shí)數(shù)類型

  • 可以使用decimal存儲(chǔ)比bigint還要大的整數(shù)
  • float和double類型是不精確的類型,支持使用標(biāo)準(zhǔn)的浮點(diǎn)運(yùn)算進(jìn)行近似計(jì)算,float占4個(gè)字節(jié),double占8個(gè)字節(jié)
  • decimal類型用于存儲(chǔ)精確的小數(shù),占用字節(jié)數(shù)按照小數(shù)和整數(shù)分別計(jì)算,每9位數(shù)占4字節(jié),小數(shù)點(diǎn)占一個(gè)字節(jié)。有效數(shù)字65,小數(shù)部分最多30。
  • 使用decimal 需要額外的空間和計(jì)算開(kāi)銷,所以應(yīng)該盡量只是在對(duì)小數(shù)進(jìn)行精確計(jì)算的時(shí)候才使用,例如存儲(chǔ)財(cái)務(wù)數(shù)據(jù)。如果數(shù)據(jù)量大,也可以考慮使用bigint來(lái)存儲(chǔ),這樣能避免使用浮點(diǎn)存儲(chǔ)不精確和decimal精確存儲(chǔ)代價(jià)高的問(wèn)題。

3.4 時(shí)間類型

時(shí)間類型統(tǒng)一用datetime,如涉及時(shí)區(qū),則用timestamp

每個(gè)表中都必須包含2個(gè)字段:create_time和edit_time
create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
edit_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改時(shí)間'

Datetime 和 Timestamp 幾乎以同樣的方式工作。兩種都保存日期和時(shí)間信息,毫秒部分最高精確度都是 6 位數(shù)。在表示日期/時(shí)間部分時(shí) Timestamp (4 字節(jié)) 比 Datetime (5 字節(jié)) 少使用 1 字節(jié)。當(dāng)保存毫秒部分時(shí)兩種都使用額外的空間 (1-3 字節(jié))。Timestamp 存儲(chǔ)范圍從 ‘1970-01-01 00:00:01.000000’ 到 ‘2038-01-19 03:14:07.999999’ 。 Datetime 存儲(chǔ)范圍從 ‘1000-01-01 00:00:00.000000’ 到 ‘9999-12-31 23:59:59.999999’ 。

3.5 NOT NULL和默認(rèn)值

除了必須為NULL,建議字段都定義為NOT NULL。因?yàn)閚ull值會(huì)影響cordinate統(tǒng)計(jì),影響優(yōu)化器對(duì)索引的選擇,而且需要額外的存儲(chǔ)空間。

3.6 同一意義的字段定義必須相同

同一意義的字段定義包括字段類型和長(zhǎng)度范圍必須相同
比如t_item表中的id和t_item_batch表中的item_id,需要定義成一樣的類型。如果類型不一樣,關(guān)聯(lián)的時(shí)候會(huì)發(fā)生強(qiáng)制類型轉(zhuǎn)換,不會(huì)用到索引。如果范圍不一樣,那么一個(gè)表正常插入,另一個(gè)表就超出范圍報(bào)錯(cuò)了。

4 SQL使用規(guī)范

4.1 不允許select * 查詢

只取出需要的字段,減少網(wǎng)絡(luò)帶寬消耗,能有效利用覆蓋索引,表結(jié)構(gòu)變更對(duì)程序基本無(wú)影響

4.2 不建議使用join,left join

請(qǐng)將復(fù)雜查詢拆分為多個(gè)簡(jiǎn)單查詢,減少鎖表的范圍和時(shí)間

4.3 拒絕高并發(fā)的計(jì)數(shù)器

不允許在mysql中進(jìn)行高并發(fā)的類計(jì)數(shù)器行為. 比如:字段+1操作

4.4 禁止where條件中使用函數(shù)

where條件中不要使用函數(shù)或進(jìn)行(隱式)強(qiáng)制轉(zhuǎn)換
例如,
1、date(create_time)='2016-11-01'改用create_time>='2016-11-01' and create_time>'2016-11-02'
2、t_preference表的latitude_no字段是varchar類型,所以在使用的時(shí)候一定要在值上加引號(hào)latitude_no='341245',不能直接latitude_no=341245,這樣會(huì)無(wú)法利用索引

4.5 不建議使用union,union all

數(shù)據(jù)量大的情況下,或者有大字段的表,不建議使用union,union all,會(huì)創(chuàng)建磁盤上的臨時(shí)表,影響性能。

4.6 不允許在數(shù)據(jù)庫(kù)端進(jìn)行復(fù)雜計(jì)算

影響sql效率,cpu消耗嚴(yán)重

4.7 拒絕大事務(wù)

比如在一個(gè)事務(wù)里進(jìn)行多個(gè)select,多個(gè)update,如果是高頻事務(wù),會(huì)嚴(yán)重影響MySQL并發(fā)能力,因?yàn)槭聞?wù)持有的鎖等資源只在事務(wù)rollback/commit時(shí)才能釋放。

4.8 盡量采用批量SQL

減少與數(shù)據(jù)庫(kù)交互的次數(shù),盡量采用批量SQL語(yǔ)句,但需要控制好個(gè)數(shù)。
例如INSERT INTO VALUES(),(),(),合并插入。

本文參考
http://seanlook.com/2016/05/11/mysql-dev-principle-ec/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容