Author:saktemysql
Time:2013/02/27sql
mysql開發規範文檔數據庫
1.mysql數據庫命名規範緩存
2.表結構設計、數據類型選擇併發
3.開發注意事項函數
1.mysql數據庫命名規範高併發
1.1 命名規範:性能
Table/view/procedure/function/package:優化
object類型簡稱+功能模塊簡稱的小寫字母+「_」+業務意義小寫單詞,如:spa
主鍵/外鍵/索引:
object類型簡稱+」_」+表名簡稱+字段名
object類型簡稱:
Table:t
View:v
Procedure:p
Function:fn
Package:pk
主鍵 :pk
外鍵 :fk
索引 :idx
Eg:
Trader後臺功能:tbk_operate_log
搜索功能表:ts_operate_log
索引命令:idx_tablename_column
2.表結構設計、數據類型選擇
2.1 經常使用數據類型:
整型:tinyint,smallint,mediumint,int,bigint。通常int就夠用了
浮點型:DECIMAL(M,D)精準,不建議用DECIMAL,建議乘以固定倍數轉換成整數存儲,能夠節省存儲空間,且不會帶來任何附加維護成本
TINYINT>SMALLINT>MEDIUMINT>INT>BIGINT>DECIMAL(存儲空間逐漸變大,而性能卻逐漸變小)。
自增序列類型的字段只能使用int或bigint,且明確標識出無符號型(unsigned),當該字段超過42億時,才使用bigint
字符型:varchar,char,ENUM和SET,text
字符列選擇類型時,儘可能不要使用TEXT數據類型,lob類型更是要堅定杜絕,僅當字符數超過20000時,能夠採用text類型,且全部使用text類型的字段,必須和原表拆分,與原表主鍵單獨存儲在另一個表裏。它的處理方式決定了它的性能要低於char或者是varchar類型的處理。定長字段,建議使用CHAR類型,不定長字段儘可能使用VARCHAR,且僅僅設定適當的最大長度,而不是很是隨意的給一個很大的最大長度限定,由於不一樣的長度範圍,MySQL也會有不同的存儲處理。對於狀態字段,能夠採用char類型,也能夠嘗試使用ENUM來存放,由於能夠極大的下降存儲空間,並且即便須要增長新的類型,只要增長於末尾,修改結構也不須要重建表數據。若是是存放可預先定義的屬性數據呢?能夠嘗試使用SET類型,即便存在多種屬性,一樣能夠遊刃有餘,同時還能夠節省不小的存儲空間。
日期時間:經常使用TIMESTAMP,date
須要精確(年月日時分秒)的時間字段,可使用datetime,timestamp ;若是時間字段只須要精確到天,那就用date類型
2.2 表結構基本設計:
2.2.1.字段字段使用not null:
MySQL NULL類型和Oracle的NULL有差別,會進入索引中,若是是一個組合索引,那麼這個NULL類型的字段會極大影響整個索引的效率。此外,NULL 在索引中的處理也是特殊的,也會佔用額外的存放空間
2.2.2.適當的拆分/冗餘
A.當咱們的表中存在相似於 TEXT 或者是很大的 VARCHAR類型的大字段的時候,若是咱們大部分訪問這張表的時候都不須要這個字段,咱們就該義無反顧的將其拆分到另外的獨立表中,以減小經常使用數據所佔用的存儲空間。這樣作的一個明顯好處就是每一個數據塊中能夠存儲的數據條數能夠大大增長,既減小物理 IO 次數,也能大大提升內存中的緩存命中率。
B.被頻繁引用且只能經過Join 2張(或者更多)大表的方式才能獲得的獨立小字段,這樣的場景因爲每次Join僅僅只是爲了取得某個小字段的值,Join到的記錄又大,會形成大量沒必要要的IO,徹底能夠經過空間換取時間的方式來優化。不過,冗餘的同時須要確保數據的一致性不會遭到破壞,確保更新的同時冗餘字段也被更新。
2.2.3.控制表的大小
mysql在處理大表(char的表>500W行,或int表>1000W)時,性能就開始明顯下降,因此要採用不一樣的方式控制單表容量
A:根據數據冷熱,對數據分級存儲,歷史歸檔
B:採用分庫/分表/分區表,橫向拆分控制單表容量
C:對於OLTP系統,控制單事務的資源消耗,遇到大事務能夠拆解,採用化整爲零模式,避免特例影響大衆
D:單庫不要超過500個表
E:單表字段數不要太多,最多不要大於50個
2.2.4.表的定義參數
mysql> show create table utf8\G;
*************************** 1. row ***************************
Table: utf8
Create Table: CREATE TABLE `utf8` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
`createtime` timestamp NULL DEFAULT NULL,
`istrue` tinyint(4) DEFAULT '1',
`a` decimal(10,0) DEFAULT NULL,
`b` decimal(10,4) DEFAULT NULL,
`c` datetime DEFAULT NULL,
`d` date DEFAULT NULL,
`e` enum('a','b','c') DEFAULT NULL,
`f` set('a','b','c') DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name_UNIQUE` (`name`),
UNIQUE KEY `createtime_UNIQUE` (`createtime`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=dynamic
engine:根據本身的業務須要選擇合適的存儲引擎,通常事務表選擇innodb,只讀表選擇myisam
AUTO_INCREMENT:自增列的初始化值
CHARSET:根據本身業務需求,定義表的字符集,對於多種語言環境選擇utf8
ROW_FORMAT:行的存儲格式
說明:
mysql文件存儲格式
antelope
Barracuda
mysql行存儲格式
antelope:提供compact和redundant兩種行格式,redundant爲兼容以前版本保留的。默認狀況下保存的格式爲compact格式
Barracuda:Innodb plugin引入新的文件格式,Barracuda文件格式包含兩種新的行記錄格式:Dynamic和Compressed。Compressed對於字符類型數據有很好壓縮功能,能夠提升效率
2.2.5.建立合適所索引
索引須要額外的維護成本、訪問成本和空間成本,因此建立索引必定要謹慎,使單個索引儘可能覆蓋多的sql,更新頻率比較高的表要控制索引的數量。
A. 對於很是大更新量的數據,索引的維護成本會很是高,若是其檢索需求不多,並且對檢索效率並無很是高的要求的時候,並不建議建立索引,或者是儘可能減小索引。
B. 對於數據量極小到經過索引檢索還不如直接遍從來得快的數據,也並不適合使用索引。
C. 應該儘可能讓查找條件儘量多的在索引中,儘量經過索引完成全部過濾,回表只是取出額外的數據字段。
D. 字段的順序對組合索引效率有相當重要的做用,過濾效果越好的字段須要更靠前
E. 須要讀取的數據量佔整個數據量的比例較大或者說索引的過濾效果並非太好的時候,使用索引並不必定優於全表掃描。
F. 在實際使用過程當中,一次數據訪問通常只能利用1個索引,這一點在索引建立過程當中必定要注意,不是說一條SQL語句中Where子句裏面每一個條件都有索引能對應上就能夠了.
G.在高併發環境不要使用外鍵,太容易產生死鎖,應由程序保證約束
H.字符字段必須使用前綴索引。
3. 開發注意事項
3.1 不在索引列上進行數學運算或函數運算
3.2 避免大sql,拆解多個小sql
3.3 避免是用select *
3.4 用in() /union替換or,並注意in的個數小於300
3.5 避免使用%前綴模糊前綴查詢
3.6 避免使用子查詢