1. 程式人生 > >MySQL資料庫設計規範說明

MySQL資料庫設計規範說明

目的

為了規範資料庫設計,減少設計失誤,提高資料安全及效能,特制訂本規範。

適用範圍

所有mysql資料庫。原則上,資料庫設計應遵循本規範說明,特殊情況可例外,但需跟DBA說明原因。

規範

命名

庫名、表名、欄位名必須使用小寫字母,並採用下劃線分割

a)MySQL有配置引數lower_case_table_names,不可動態更改,linux系統預設為 0,即庫表名以實際情況儲存,大小寫敏感。如果是1,以小寫儲存,大小寫不敏感。如果是2,以實際情況儲存,但以小寫比較。

b)如果大小寫混合使用,可能存在abc,Abc,ABC等多個表共存,容易導致混亂。

c)欄位名顯式區分大小寫,但實際使用不區分,即不可以建立兩個名字一樣但大小寫不一樣的欄位。

d)為了統一規範, 庫名、表名、欄位名使用小寫字母。

庫名、表名、欄位名禁止超過32個字元

庫名、表名、欄位名支援最多64個字元,但為了統一規範、易於辨識以及減少傳輸量,禁止超過32個字元。

庫名、表名、欄位名禁止使用MySQL保留字

當庫名、表名、欄位名等屬性含有保留字時,SQL語句必須用反引號引用屬性名稱,這將使得SQL語句書寫、SHELL指令碼中變數的轉義等變得非常複雜。

原則上,業務範疇內的表都統一使用innodb儲存引擎;如需使用其它儲存引擎,需說明原因,並徵得DBA同意。

innodb引擎是MySQL5.5版本以後的預設引擘,支援事務、行級鎖,有更好的資料恢復能力、更好的併發效能,同時對多核、大記憶體、SSD等硬體支援更好,支援資料熱備份等,因此INNODB相比MyISAM有明顯優勢。

myisam不夠可靠,容易損壞丟失資料。

myisam不支援事務;如果存在myisam與innodb混用的話,事務資料的一致性存在風險。

myisam讀寫阻塞,不適用於高併發環境;innodb支援行級鎖。

myisam不支援線上熱備,配置複製時可能需要停機或者長時間鎖表。

如果兩種引擎混用,會給資源分配帶來問題。因為有很多引數和設定需要停庫才能修改,為了減少停庫次數,我們目前都是採用預先最大化分配足額記憶體和磁碟空間的方式去做的。而myisam和innodb在記憶體和空間使用上都不一樣,如果兩者混用,那分配的時候就很難兩方都照顧到。如果兩者都按比例分配,很可能存在資源不能充分利用的情況;且隨著業務的變化,需要調整的話,也會存在停機問題。

運維需要收集很多的執行狀態資料,innodb有非常多的狀態資料可收集;而對於myisam引擎,能收集到的資料非常有限,不利於我們做監控和容量規劃。

使用外部引擎

目前常用的全文索引引擎有sphinxlucene等,適合併發高,資料量大,業務邏輯複雜的場景。主要關注預熱、增量更新及分片功能的實現。

異構同步引擎有mysql2redis、tair 等,主要解決資料項cache 的同步

禁止使用分割槽表

分割槽表對分割槽鍵有嚴格要求;分割槽表在表變大後,執行DDL、SHARDING、單表恢復等都變得更加困難。因此禁止使用分割槽表,並建議業務端手動SHARDING。

減少或避免使用臨時表

為了切換後可以正常工作,無論主備,相同的表需使用相同的引擎。

相同的表在主備可以使用不同的引擎或者獲得更好地效能,但是給管理帶來複雜性,也給業務帶來隱患。在我們的DB環境,應用程式切換連線DB是常態,因此,需要嚴格保持主備資料和表結構的一致性。

每一個表都需要設定主鍵

表沒有主鍵,INNODB會預設設定隱藏的主鍵列;沒有主鍵的表在定位資料行的時候非常困難,也會降低基於行復制的效率。

將大欄位、訪問頻率低的欄位拆分到單獨的表中儲存,分離冷熱資料

有利於有效利用快取,防止讀入無用的冷資料,較少磁碟IO,同時保證熱資料常駐記憶體提高快取命中率。

正規化

表不要求一定滿足第三正規化,根據實際情況可適當新增冗餘欄位。

我們的原則是一個SQL最好只操作一個表,最多不能超過2個表的關聯。如果實現一個常用的功能需要一個關聯多表的查詢,則需要重新考慮設計。

由程式保證冗餘資料的維護。

約束

對於字典型別的表,因資料量小,修改少,影響面大,應依賴資料庫約束來確保資料質量。

對於日誌或流水型表,為了提升效率,可以釋放放寬限制。

之所以分開,是從效能以及影響面考慮的。

對於字典型別的資料,因為修改少,約束給其效能帶來的負面影響忽略。但是一個數據欄位的資料錯誤,影響面非常廣,因此,需要非常嚴謹。前段程式或者手工新增此類資料時,容易出現錯誤,因此需要通過約束來保證其資料的質量。

日誌或者流水型表剛好相反,它一般隻影響個別使用者,但資料量較大,修改較為頻繁,效能優先。

欄位

對於欄位設計,概況下來一個原則是:越簡單越好,越小越好。

常用資料型別介紹:

資料型別 取值範圍 佔用空間(位元組)
tinyint [unsigned] -128到127或0到255  1
smallint [unsigned]  -32768到32767或0到65536  2
int [unsigned]  -2147483648到2147483647或0到4294967295  4
bigint [unsigned]  -9223372036854775808到9223372036854775807

0到18446744073709551615
 8
date  yyyy-mm-dd,精確到天  3
datetime  yyyy-mm-dd hh24:mi:ss 精確到秒  8
timestamp  yyyy-mm-dd hh24:mi:ss
精確到秒,只能儲存1970到2037年之間的時間
 4
char(m)  0<M<=255  m個字元( 非位元組)。具體空間與字符集相關
varchar(m)  0<m<=(65532/n)  m個字元。與字符集有關,最多不超過65532位元組
text  64K個字元  與字符集相關

 選擇最合適的資料型別,能用數字型別不用varchar型別;能用date/datetime型別不用varchar型別;避免使用char型別;不使用浮點數,可以通過乘以一個係數來轉換為整型資料。

在大部分情況下,資料型別比varchar型別更省空間,計算效能更高。

char型別佔用固定空間,在很多時候會造成空間浪費。

 儘量避免text/lob型別

text和lob在行內只儲存指標,實際資料是在行外單獨儲存的。使用這些資料型別,查詢時需要更多的IO。

如果SQL引用了text/lob欄位,排序等操作需要用到隱式臨時表時,只能用到disk臨時表,不能用in-memory臨時表。對效能影響巨大。

如果也許需要用text/lob型別,建議把這些欄位和其他欄位分離,放在單獨的表中。

 欄位長度定義遵循最小化原則,夠用就行,不能貪圖方便定義很大的長度。

過大的長度容錯性高,容易出現低質量資料。

定義大長度會消耗更多的空間(需要用額外的位元組儲存長度)

在很多時候,mysql或其他程式(如mysqldump)會以列的長度定義來分配使用記憶體,過大的欄位長度定義會消耗更多的記憶體。甚至還有可能原來可以在記憶體執行的排序變為磁碟排序了。

 欄位實際值也遵循最小化原則,在滿足業務需求的前提下,選擇最合適的資料型別,寫入最少的資料

ID一般無具體意義,優先使用數字來用於ID欄位,杜絕濫用長字串ID。

對於狀態之類的欄位,用0/1之類的數字代替valid/invalid等。

 對於字元型別,欄位長度定義的是字元個數,而不是位元組個數,所佔空間與字符集相關。對於int型別,佔用空間是固定的,指定長度的話只是制定了顯示長度。

varchar(25000)不一定能儲存25000個字元,如果都是漢字,且是utf8字符集的話,只能儲存65532/3個字元。

int(1)和int(11)佔用空間是一樣的,1和11只是代表顯示長度,與實際資料儲存無關。另外,在允許的範圍內,往int欄位寫入不同的值,如insert t values(1)和insert t values(9999)佔用空間一樣。

區分使用DATETIME和TIMESTAMP。儲存年使用YEAR型別。儲存日期使用DATE型別。 儲存時間(精確到秒)建議使用TIMESTAMP型別。

DATETIME和TIMESTAMP都是精確到秒,優先選擇TIMESTAMP,因為TIMESTAMP只有4個位元組,而DATETIME8個位元組。同時TIMESTAMP具有自動賦值以及自動更新的特性。注意:在5.5和之前的版本中,如果一個表中有多個timestamp列,那麼最多隻能有一列能具有自動更新功能。

使用TIMESTAMP的自動賦值屬性

a)自動初始化,並自動更新: column1 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

b)只是自動初始化: column1 TIMESTAMP DEFAULT CURRENT_TIMESTAMP

c)自動更新,初始化的值為0: column1 TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP

d)初始化的值為0: column1 TIMESTAMP DEFAULT 0

一個表的欄位個數控制在30-50個欄位以內;如果欄位超過50個,可考慮將欄位按冷熱程度分表。

這樣做雖然會給應用帶來更多的程式碼開發量,但對於熱表來說,這樣做可以提升buffer利用率,減少IO,提升查詢的效率。

 嚴格禁止單條記錄超過8K

目前我們的DB一個page大小都設定為16K,當一條記錄拆過page的一半(8K)時,記錄中的blob/varchar會在行外儲存。存取時會有額外IO消耗。插入操作會鎖住整個聚簇索引(X Index Lock),直到插入完成才釋放。

建議每一個重要的業務表都加上 create_time 和 modify_time 兩個欄位,資料型別為datetime;後續的所有更新都必須更新modify_time欄位。

增加欄位會帶來額外的資源消耗,但考慮到它可能能帶來的好處,還是值得新增的。

這兩個欄位可以與業務時間重合重用。

對於可能出現在where條件中的欄位,儘量設定為非空(not null)

B*Tree索引不能索引空值(null)。欄位值為空的話,在部分查詢不能有效使用索引。

欄位字符集與表保持一致,不單獨設定字符集。

相同含義的欄位在不同表中應使用相同的名稱,資料型別及長度必須保持一致。

索引/主鍵設計

Innodb表每一個表都要設定主鍵。主鍵越短越好,最好是auto_increment型別;如果不能使用自增,則應考慮構造使用單向遞增型主鍵;禁止使用隨機型別值用於主鍵。

使用innodb,每一個表都必須有主鍵。如果沒有指定主鍵,mysql會選擇一個非空的唯一鍵作為主鍵;如果都沒有,mysql會自動分配6-bytes長的全域性的rowid隱藏列作為主鍵。所有InnoDB非主鍵表共享這一序列,併發效能較差,因此建議所有InnoDB表,指定主鍵。

所有的輔助索引都包含主鍵欄位,因此,如果主鍵過大的話,會影響所有的索引大小。

遞增型主鍵可以讓索引更緊湊、空間利用更充分、資料插入更高效。隨機資料會讓空間大量浪費,且會導致索引分裂加劇,離散IO增多,極大影響DML效能。

主鍵最好由一個欄位構成,最多不要超過3個,禁止超過3個欄位的組合主鍵。如果業務要求,則可以建立一個自增欄位作為主鍵,再新增一個唯一索引。

多列主鍵會導致其他索引體積膨脹,佔用更多的空間,並降低效能。

使用多列業務主鍵的話,對主鍵來說,一般可認為是隨機插入。

如果查詢都是基於主鍵欄位,且只有1個及以下輔助索引,則限制可以放寬。

如果一個業務上存在多個(組)唯一鍵,以查詢最常用的唯一鍵作為主鍵。

索引會降低DML的效能,不是越多越好,只建立需要的索引,避免冗餘索引。

建立索引需考慮返回資料量、對DML的影響,以及受其影響的查詢SQL的執行頻率。

選擇作為主鍵的列必須在插入後不再修改或者極少修改,否則需考慮使用自增列作為主鍵。

建立組合索引/主鍵時,常用的欄位放在前面;選擇性高的欄位放在前面。

兩者衝突時,以常用為更優先選擇。

建立組合索引時,如果where條件中過濾性不強,且需要排序分頁操作,建議把排序欄位也加到組合索引中,放在組合索引最後列。

如col1 + col 2可以過濾出來10000條資料,當有如下SQL時,建議把col3也加到索引中:

select col1,col2...coln from t where col1=xx and col2=xx order by col3 limit n;

對較長的字元資料型別的欄位建索引,優先考慮字首索引。

低選擇性的列不加索引,例如”性別”

如性別欄位加索引意義不大

狀態欄位一般不加索引。例外情況是,狀態資料分佈很傾斜,且查詢條件中沒有其他更適合索引的欄位,如status=1佔99%資料,status=2佔1%資料,查詢SQL為:select col1,col2... from t where status=2;

禁止冗餘索引

索引是雙刃劍,會增加維護負擔,增大IO壓力。(a,b,c)、(a,b),後者為冗餘索引。可以利用字首索引來達到加速目的,減輕維護負擔。

在建表時,應充分考慮需要新增什麼索引,儘量避免上線後新增索引

分庫分表

如果資料有時效性,則建議按時間分表或者分割槽

如可以年、月、天分表。代表如提現單流水錶。

分表的粒度應該和實際資料量結合,慎用按天分表。原則上,我們以單表1G作為分表的界限。

杜絕按天分庫。

如果也許必須按天分表,考慮到一個檔案下不應存放過多檔案,建議可根據年份分庫,然後把按天分的表放在對應的庫中。

 如果所有資料熱度相同,則建議根據hash或者其他手段分庫分表

目前最常用的是根據分表方式是分百庫十表,共1000個表。具體規則是:取分表字段(如ID)的後三位,其中後兩位是庫的ID(00-99),倒數第三位是表的ID(0-9);

 杜絕只按月份,不考慮年份方式分表

目前發現有不少表是按月份分12張表,不同年份的資料會儲存在一張表裡。這種做法不利於歷史資料的管理,且會降低buffer的利用率。

此種情況,建議按YYYYMM方式分表。

 如果多個獨立業務需要共用一臺DB的話,不同業務的表必須放在不同的database(schema)裡

主要考慮管理便捷和安全。

 對於分庫分表,每一個表的索引結構及名稱都必須一致

其它

開發在提交資料庫新增物件請求單時,需按附件模板提供足夠的資訊供DBA決策

根據這些資訊,DBA可以做容量、效能評估,決定需要什麼樣的硬體支援。

示例:

表名 t_order_x
DDL 詳見req檔案(如果少的話,可直接附在這裡)
用途 使用者訂單表
未來一年資料量預測 每天增量200W條
是否分表
分表方式 百庫十表
活躍資料範圍 最近3月
核心SQL及執行頻率 select col1,col2 from c2c_db_00.t_order_1 where flistid='xxxxx';每天執行400W次
需求提出者 developer name
其他說明

相關推薦

收集整理mysql資料庫設計規範與原則

1、 資料庫命名規範  採用26個英文字母(區分大小寫)和0-9的自然數(經常不需要)加上下劃線'_'組成;命名簡潔明確(長度不能超過30個字元);例如:user, stat, log, 也可以wifi_user, wifi_stat, wifi_log給資料庫加個字首;除非是備份資料庫可以加0-9的自然數:

MySQL 資料庫設計規範 詳解

1> 資料庫涉及字元規範採用 26 個英文字母(區分大小寫) 和 0-9 這十個自然數,加上下劃線'_'組成,共 63 個字元,不能出現其他字元(註釋除外)注 : 1> 以上命名都不得超過 30 個字元的系統限制,變數名的長度限制為 29(不包括標識字元@)   

MYSQL資料庫設計規範與原則

MYSQL資料庫設計規範 1、資料庫命名規範 採用26個英文字母(區分大小寫)和0-9的自然數(經常不需要)加上下劃線'_'組成; 命名簡潔明確(長度不能超過30個字元); 例如:user, stat, log,

MySQL資料庫設計規範

MySQL 資料庫設計規範 目錄 基礎規範 索引規範 SQL設計 1. 基礎規範 ^ 1.1. 使用Innodb儲存引擎 1.2. 表字符集統一使用UTF8 如果遇到 EMOJ 等表情符號的儲存需求,可使用 utf

MySQL資料庫設計規範說明

目的 為了規範資料庫設計,減少設計失誤,提高資料安全及效能,特制訂本規範。 適用範圍 所有mysql資料庫。原則上,資料庫設計應遵循本規範說明,特殊情況可例外,但需跟DBA說明原因。 規範 命名 庫名、表名、欄位名必須使用小寫字母,並採用下劃線分割 a)

Mysql資料庫設計規範設計原則

一、MYSQL資料庫設計規範       1、資料庫命名規範         採用26個英文字母(區分大小寫)和0-9的自然數(經常不需要)加上下劃線'_'組成;         命名簡潔明確(長度不能超過30個字元);         例如:user, stat, log,

阿里巴巴MYSQL資料庫設計,查詢規範

MySQL資料庫 (一)建表規約 1.【強制】表達是與否概念的欄位,必須使用is_xxx的方式命名,資料型別是unsignedtinyint(1表示是,0表示否) 。說明:任何欄位如果為非負數,必須是unsigned。正例:表達邏輯刪除的欄位名is_d

MySQL學習筆記_資料庫設計規範

資料庫設計的規範:一.資料庫命名規範二.資料庫基本設計規範三.資料庫索引設計規範四.資料庫欄位設計規範五.資料庫SQl開發規範六.資料庫操作行為規範一.資料庫命名規範1.所有的資料庫名稱和表名稱必須使用小寫字母並使用下劃線分割  這是因為MySQL資料檔案就是Linux下的一

Mysql資料庫設計規範

1. 三大正規化 首先要明白”正規化(NF)”是什麼意思。按照教材中的定義,正規化是“符合某一種級別的關係模式的集合,表示一個關係內部各屬性之間的聯絡的合理化程度”。資料庫正規化也分為1NF,2NF,3NF,BCNF,4NF,5NF。一般在我們設計關係型資料庫

資料庫設計規範MYSQL、WEB)

一、命名規範 1. 資料庫、表、欄位、別名規範 識別符 最大長度(位元組) 允許的字元 資料庫 64 [a-z_] (所有字元均小寫, 字之間用 _ 分割) 表 64 [a-z_] (所有字元均小寫, 字之間用 _ 分割) 列 64 [a-z_] (所有字元均小寫, 字之間用 _ 分

MySQL資料庫優化——資料庫設計規範

資料庫命名規範   採用26個英文字母(區分大小寫)和0-9的自然數(經常不需要)加上下劃線'_'組成; 命名簡潔明確(長度不能超過30個字元); 例如:user, stat, log, 也可以wifi_user, wifi_stat, wifi_log給資料庫

#資料庫設計規範

資料庫設計規範, 一二三正規化,E-R模型 1.資料庫表的設計正規化(三正規化和反正規化) E-R圖的基本成分包括實體型別、屬性和聯絡 1. 實體:用矩形表示,框內註明實體名稱。 2. 屬性;用橢圓表示,框內標註屬性名稱,並用無向邊

mysql資料庫設計中的14個技巧

mysql資料庫設計中的14個技巧     1. 原始單據與實體之間的關係  可以是一對一、一對多、多對多的關係。在一般情況下,它們是一對一的關係:即一張原始單據對應且只對應一個實體。在特殊情況下,它們可能是一對多或多對一的關係,即一張原始單證對應多個實

mysql - 資料庫設計

資料庫設計可以採用面向物件的思想去設計沒一張表,每一個檢視,併為資料庫中一些關鍵表新增關聯關係的觸發器(create trigger),如級聯刪除、級聯更新、級聯新增。 或者是追求處理效能的儲存過程和儲存函式。 那麼 在設計的過程中,有的人可能會考慮自己我這樣設計的表結構合不合理?存

MySql 開發設計規範

1.杜絕直接 SELECT * 讀取全部欄位    即使需要所有欄位,減少網路頻寬消耗,能有效利用覆蓋索引,表結構變更對程式基本無影響 2.能確定返回結果只有一條時,使用 limit 1    在

資料庫設計規範(適用併發量大、資料量大的網際網路業務)

一、基礎規範 (1)必須使用InnoDB儲存引擎 解讀:支援事務、行級鎖、併發效能更好、CPU及記憶體快取頁優化使得資源利用率更高 (2)必須使用UTF8字符集 解讀:萬國碼,無需轉碼,無亂碼風險,節省空間 (3)資料表、資料欄位必須加入中文註釋 解讀:N年後誰tm知道這個r1,r2,r

MySQL資料庫設計總結

規則1:一般情況可以選擇MyISAM儲存引擎,如果需要事務支援必須使用InnoDB儲存引擎。 注意:MyISAM儲存引擎 B-tree索引有一個很大的限制:參與一個索引的所有欄位的長度之和不能超過1000位元組。另外MyISAM資料和索引是分開,而InnoDB的資料儲存

MySQL 資料庫設計

資料庫需求分析: 1.由使用者發表作品  其他已註冊使用者 在瀏覽個使用者發表的作品時可以進行 點贊 評論 (同時可以撤銷點贊) 2.同時對評論的內容也可以進行相應的點贊 (同時可以撤銷點贊) 3.以及後期規劃 對評論的使用者可以進行相應的回覆 設計流程: 1.

MySQL資料庫開發規範50條

所有的資料庫物件名稱必須使用小寫字母並用下劃線分割(MySQL大小敏感,見名知意,最好不超過32字元) 所有的資料庫物件名稱禁止使用MySQL保留關鍵字(如 desc、range、match、delayed 等,請參考 MySQL 官方保留字http://dev.mysql.com/doc/refm

【乾貨】MySQL資料庫開發規範

所有的資料庫物件名稱必須使用小寫字母並用下劃線分割(MySQL大小寫敏感,名稱要見名知意,最好不超過32字元) 所有的資料庫物件名稱禁止使用MySQL保留關鍵字(如 desc、range、match、delayed 等,請參考 MySQL官方保留字 ) 臨時庫表必須以t