課程準備: MySQL 5.7版本+SQLyog數據庫
數據庫設計規範緩存
全部的數據庫對象名稱必須使用小寫字母並用下劃線分割(數據庫名 表名 列名...) 大小寫敏感服務器
全部的數據庫對象名稱禁止使用MySQL保留關鍵字網絡
全部的數據庫對象命名作到見名識義,最多不超過32個字符併發
例如:用戶數據庫 mc_userdb運維
用戶帳號表 user_account數據庫設計
臨時庫表必須以tmp_爲前綴以日期爲後綴函數
備份庫、備份表以bak_爲前綴並以日期爲後綴高併發
全部存儲相同數據的列名和列類型必須一致性能
MySQL5.5使用以前Myisam(默認存儲引擎)全部表必須使用Innodb存儲引擎,(特殊需求:列存儲除外,空間數據) 5.6之後的默認Innodb存儲引擎,支持事務,行級鎖,更好的恢復性,高併發下性能更好。
數據庫和表的字符集統一使用UTF8,兼容性更好,避免亂碼。
全部表和字段都要添加註釋COMMENT,從一開始就進行數據字典的維護
儘可能控制單表數據量的大小,建議控制在500萬行內,但500萬行不是MySQL數據庫的限制。過大對於修改表結構,備份,恢復都會有很大問題。MySQL沒有對存儲有限制,取決於存儲設置和文件系統。
可使用歷史數據歸檔,分庫分表等手段來實現控制數據量大小
謹慎使用MySQL分區表
分區表在物理上表現爲多個文件,在邏輯上表現爲一個表
謹慎選擇分區鍵,跨區查詢效率可能更低
建議採用物理分表的方式管理大數據
儘可能作到冷熱數據分離,減少表的寬帶
MySQL限制最多存儲4096列,且每行不能超過65535字節。足夠大了
減小磁盤IO,保證熱數據的內存緩存命中率
更有效的利用緩存,避免讀入無用的冷數據
常常一塊兒使用的列放在一個表中
禁止在表中創建預留字段
其實很牽強,沒法確認預留字段的數據類型
對預留字段類型進行修改,會對錶進行鎖定
禁止在數據庫中存儲圖片,文件等二進制數據
使用文件服務器
禁止在線上數據庫壓力測試
禁止從開發環境,測試環境直接連生產環境數據庫
"雙刃劍"
避免創建冗餘索引和重複索引
冗餘:index(a,b,c) index(a,b) index(a)
限制每張表的索引數量,建議單張表索引不超過5個
索引不是越多越好!索引能夠提升效率一樣也能夠下降效率
索引能夠增長查詢效率,但一樣也會下降插入和更新效率
禁止給表中的每一列都創建單獨的索引
Innodb是按照哪一個索引的順序來組織表的呢?答案:主鍵
每一個Innodb表必須有一個主鍵(或者非空惟一的字段或自動生成的可是性能不大好)
不使用更新頻繁的列做爲主鍵,不能用多列作主鍵(聯合索引)
不適用UUID,MD5,HASH,字符串列做爲主鍵
建議主鍵使用自增ID值
常見索引列建議:select update delete語句的where從句的列
包含order by group by distinct中的字段 組成聯合索引
多表join的關聯列
如何選擇索引列的順序:
區分度最高(重複率低)的列放在聯合索引的最左側
字段長度小的列放在聯合索引的最左側
使用最頻繁的列房到聯合索引的左側
若是一個索引包含(或覆蓋)全部須要查詢的字段的值,稱爲‘覆蓋索引’。即只需掃描索引而無須回表。
儘可能避免使用外鍵
不建議使用外鍵約束,但必定在表與表之間的關聯鍵上創建索引
優先選擇符合須要的最小數據類型
好比:字符串轉數字類型存儲 INET_ACTION('255.255.255.0')=4294967295
INET_NTOA(4294967295)='255.255.255.0'
對於非負的數據來講,要優先使用無符號整型來存儲 UNSIGNED
VARCHAR(N)中的N表明的是字符數,而不是字節數
使用UTF8存儲漢字VARCHAR(255)=765個字節
過大的定義長度會消耗更多的內存
避免使用TEXT,BLOG數據類型,使用varchar()或者把BLOB或者TEXT列分離到單獨的擴展表中。
避免使用枚舉ENUM數據類型
儘量把全部列定義爲NOT NULL
因爲索引NULL列須要額外的空間來保存,因此要佔用更多的空間
進行比較和計算時要對null值作特別的處理
使用timestamp或者datetime存儲時間類型 timestamp更小4字節,另外一個8字節但有範圍限制
財務相關的金額類數據,使用decimal數據類型(精準浮點)float和double屬於非精準浮點類型
避免使用雙%號 和 like
使用left join 或not exists來優化not in操做
禁止跨庫查詢 爲數據遷移和分庫分表留出餘地,下降耦合度,下降風險
禁止使用select *
消耗更多的cpu和io以及網絡帶寬資源
沒法使用覆蓋索引
減少表結構變動帶來的影響
禁止使用不含字段列表的insert語句
insert into t values(‘a’,‘b’,‘c’);不容許
insert into t (c1,c2,c3)values(‘a’,‘b’,‘c’);
避免使用子查詢,能夠把子查詢優化爲join操做(通常狀況);
由於子查詢的結果集沒法使用索引
子查詢會產生臨時表,若是子查詢數據量大會嚴重影響效率
消耗過多的cpu以及io資源
避免使用join關聯太多的表,意見不超過5個
每join一個表多佔用一部份內存(join_buffer_size)
會產生臨時表操做,影響查詢效率
減小同數據庫的交互次數
數據庫更適合批量操做
合併多個相同的操做到一塊兒,可提升處理效率
例如:alter操做 add和change一塊兒
使用in代替or in裏的值不要超過500個
禁止使用order by rand()進行隨機排序
禁止where從句中對列進行函數轉換和計算
例如:where date(createtime)=‘20160901’ 會沒法使用createtime列上索引
改爲 where createtime>='20160901'
and createtime <'20160902'
儘可能 union all 代替 union
拆分複雜的大SQL爲多個小SQL
MySQL一個SQL只能使用一個CPU進行計算
對於大表修改使用pt-online-schema-change修改表結構
避免大表修改產生的主從延遲
避免在對錶字段進行修改時進行鎖表
禁止爲程序使用的帳號賦予super權限
對於程序鏈接數據庫帳號,遵循權限最小原則