MySQL運維及開發規範

一.基礎規範mysql

(1) 使用INNODB存儲引擎
(2) 表字符集使用UTF8
(3) 全部表都須要添加註釋
(4) 單表數據量建議控制在5000W之內
(5) 不在數據庫中存儲圖、文件等大數據
(6) 禁止在線上作數據庫壓力測試
(7) 禁從測試、開發環境直連數據庫sql

二.命名規範
(1) 庫名錶名字段名必須有固定的命名長度,12個字符之內
(2) 庫名、表名、字段名禁止超過32個字符。須見名之意
(3) 庫名、表名、字段名禁止使用MySQL保留字
(4) 臨時庫、表名必須以tmp爲前綴,並以日期爲後綴
(5) 備份庫、表必須以bak爲前綴,並以日期爲後綴數據庫

三.庫、表、字段開發設計規範
(1) 禁使用分區表
(2) 拆分大字段和訪問頻率低的字段,分離冷熱數據
(3) 用HASH進散表,表名後綴使進制數,下標從0開始
(4) 按日期時間分表需符合YYYY[MM][DD][HH]格式
(5) 採用合適的分庫分表策略。例如千庫十表、十庫百表等
(6) 儘量不使用TEXT、BLOB類型
(7) 用DECIMAL代替FLOAT和DOUBLE存儲精確浮點數
(8) 越簡單越好:將字符轉化爲數字、使用TINYINT來代替ENUM類型
(9) 全部字段均定義爲NOT NULL
(10) 使用UNSIGNED存儲非負整數
(11) INT類型固定佔用4字節存儲
(12) 使用timestamp存儲時間
(13) 使用INT UNSIGNED存儲IPV4
(14) 使用VARBINARY存儲大小寫敏感的變長字符串
(15) 禁止在數據庫中存儲明文密碼,把密碼加密後存儲
(16) 用好數值類型字段
Tinyint (1Byte)
smallint (2Byte)
mediumint (3Byte)
int (4Byte)
bigint (8Byte)
若是數值字段沒有那麼大,就不要用 bigint
(17) 存儲ip最好用int存儲而非char(15)
(18) 不容許使用ENUM
(19) 避免使用NULL字段
NULL字段很難查詢優化,NULL字段的索引須要額外空間,NULL字段的複合索引無效
(20) 少用text/blob,varchar的性能會比text高不少,實在避免不了blob,請拆表
(21) 數據庫中不容許存儲大文件,或者照片,能夠將大對象放到磁盤上,數據庫中存儲它的路徑緩存

四.索引規範
一、索引的數量要控制:
(1) 單張表中索引數量不超過5個
(2) 單個索引中的字段數不超過5個
(3) 對字符串使用前綴索引,前綴索引長度不超過8個字符
(4) 建議優先考慮前綴索引,必要時可添加僞列並創建索引
二、主鍵準則
(1) 表必須有主鍵
(2) 不使用更新頻繁的列做爲主鍵
(3) 儘可能不選擇字符串列做爲主鍵
(4) 不使用UUID MD5 HASH這些做爲主鍵(數值太離散了)
(5) 默認使非空的惟一鍵做爲主鍵
(6) 建議選擇自增或發號器
三、重要的SQL必須被索引,好比:
(1) UPDATE、DELETE語句的WHERE條件列
(2) ORDER BY、GROUP BY、DISTINCT的字段
四、多表JOIN的字段注意如下:
(1) 區分度最大的字段放在前面
(2) 核SQL優先考慮覆蓋索引
(3) 避免冗餘和重複索引
(4) 索引要綜合評估數據密度和分佈以及考慮查詢和更新比例
五、索引禁忌
(1) 不在低基數列上創建索引,例如「性別」
(2) 不在索引列進行數學運算和函數運算
六、儘可能不使用外鍵
(1) 外鍵用來保護參照完整性,可在業務端實現
(2) 對父表和子表的操做會相互影響,下降可用性
七、索引命名:非惟一索引必須以 idx_字段1_字段2命名,惟一因此必須以uniq_字段1_字段2命名,索引名稱必須所有小寫
八、新建的惟一索引必須不能和主鍵重複
九、索引字段的默認值不能爲NULL,要改成其餘的default或者空。NULL很是影響索引的查詢效率
十、反覆查看與表相關的SQL,符合最左前綴的特色創建索引。多條字段重複的語句,要修改語句條件字段的順序,爲其創建一條聯合索引,減小索引數量
十一、能使用惟一索引就要使用惟一索引,提升查詢效率
十二、研發要常用explain,若是發現索引選擇性差,必須讓他們學會使用hint服務器

五.SQL規範
(1) sql語句儘量簡單
大的sql想辦法拆成小的sql語句(充分利用QUERY CACHE和充分利用多核CPU)
(2) 事務要簡單,整個事務的時間長度不要太長
(3) 避免使用觸發器、函數、存儲過程
(4) 下降業務耦合度,爲sacle out、sharding留有餘地
(5) 避免在數據庫中進數學運算(MySQL不擅長數學運算和邏輯判斷)
(6) 不要用select *,查詢哪幾個字段就select 這幾個字段
(7) sql中使用到OR的改寫爲用 IN() (or的效率沒有in的效率高)
(8) in裏面數字的個數建議控制在1000之內
(9) limit分頁注意效率。Limit越大,效率越低。能夠改寫limit,好比例子改寫:
select id from tlimit 10000, 10; => select id from t where id > 10000 limit10;
(10) 使用union all替代union
(11) 避免使大表的JOIN
(12) 使用group by 分組、自動排序
(13) 對數據的更新要打散後批量更新,不要一次更新太多數據
(14) 減小與數據庫的交互次數
(15) 注意使用性能分析工具
Sql explain / showprofile / mysqlsla
https://blog.csdn.net/ls3648098/article/details/9303237
(16) SQL語句要求全部研發,SQL關鍵字所有是大寫,每一個詞只容許有一個空格
(17) SQL語句不能夠出現隱式轉換,好比 select id from 表 where id='1'
(18) IN條件裏面的數據數量要少,我記得應該是500個之內,要學會使用exist代替in,exist在一些場景查詢會比in快
(19) 能不用NOT IN就不用NOTIN,坑太多了。。會把空和NULL給查出來
(20) 在SQL語句中,禁止使用前綴是%的like
(21) 不使用負向查詢,如not in/like
(22) 關於分頁查詢:程序裏建議合理使用分頁來提升效率limit,offset較大要配合子查詢使用
(23) 禁止在數據庫中跑大查詢
(24) 使預編譯語句,只傳參數,比傳遞SQL語句更高效;一次解析,屢次使用;下降SQL注入機率
(25) 禁止使order by rand()
(26) 禁單條SQL語句同時更新多個表網絡

六.流程規範
(1) 全部的建表操做須要提早告知該表涉及的查詢sql;
(2) 全部的建表須要肯定創建哪些索引後才能夠建表上線;
(3) 全部的改表結構、加索引操做都須要將涉及到所改表的查詢sql發出來告知DBA等相關人員;
(4) 在建新表加字段以前,要求研發至少要提早3天郵件出來,給dba們評估、優化和審覈的時間
(5) 批量導入、導出數據必須提早通知DBA協助觀察
(6) 禁在線上從庫執行後臺管理和統計類查詢
(7) 禁有super權限的應用程序帳號存在
(8) 推廣活動或上線新功能必須提早通知DBA進行流量評估
(9) 不在業務高峯期批量更新、查詢數據庫session

六.配置優化規範
(1) 開啓慢查詢,用於sql語句分析。
(2) 開啓二進制日誌,用於遇到mysql崩潰,數據恢復
(3) no-auto-rehash 確保這個服務啓動得比較快。
(4) back_log = 600
在MYSQL暫時中止響應新請求以前,短期內的多少個請求能夠被存在堆棧中。若是系統在短期內有不少鏈接,則須要增大該參數的值,該參數值指定到來的TCP/IP鏈接的監聽隊列的大小。默認值80。
(5) max_connections = 3000
#MySQL容許最大的進程鏈接數,若是常常出現Too Many Connections的錯誤提示,則須要增大此值。默認151
(6) max_connect_errors = 6000
#設置每一個主機的鏈接請求異常中斷的最大次數,當超過該次數,MYSQL服務器將禁止host的鏈接請求,直到mysql服務器重啓或經過flush hosts命令清空此host的相關信息。默認100
(7) external-locking = FALSE
#使用–skip-external-locking MySQL選項以免外部鎖定。該選項默認開啓
(8) max_allowed_packet = 32M
#設置在網絡傳輸中一次消息傳輸量的最大值。系統默認值 爲4MB,最大值是1GB,必須設置1024的倍數。
(9) sort_buffer_size = 2M
#Sort_Buffer_Size 是一個connection級參數,在每一個connection(session)第一次須要使用這個buffer的時候,一次性分配設置的內存。
#Sort_Buffer_Size 並非越大越好,因爲是connection級的參數,過大的設置+高併發可能會耗盡系統內存資源。例如:500個鏈接將會消耗 500*sort_buffer_size(8M)=4G內存
#Sort_Buffer_Size 超過2KB的時候,就會使用mmap() 而不是 malloc() 來進行內存分配,致使效率下降。 系統默認2M,使用默認值便可
(10)join_buffer_size = 2M
#用於表間關聯緩存的大小,和sort_buffer_size同樣,該參數對應的分配內存也是每一個鏈接獨享。系統默認2M,使用默認值便可
(11)thread_cache_size = 300
#默認38 服務器線程緩存這個值表示能夠從新利用保存在緩存中線程的數量,當斷開鏈接時若是緩存中還有空間,那麼客戶端的線程將被放到緩存中,若是線程從新被請求,那麼請求將從緩存中讀取,若是緩存中是空的或者是新的請求,那麼這個線程將被從新建立,若是有不少新的線程,增長這個值能夠改善系統性能.經過比較 Connections 和 Threads_created 狀態的變量,能夠看到這個變量的做用。設置規則以下:1GB 內存配置爲8,2GB配置爲16,3GB配置爲32,4GB或更高內存,可配置更大。
(12)thread_concurrency = 8
#系統默認爲10,使用10先觀察 ,設置thread_concurrency的值的正確與否, 對mysql的性能影響很大, 在多個cpu(或多核)的狀況下,錯誤設置了thread_concurrency的值, 會致使mysql不能充分利用多cpu(或多核), 出現同一時刻只能一個cpu(或核)在工做的狀況。thread_concurrency應設爲CPU核數的2倍. 好比有一個雙核的CPU, 那麼thread_concurrency的應該爲4; 2個雙核的cpu, thread_concurrency的值應爲8
(13)query_cache_size = 64M
#在MyISAM引擎優化中,這個參數也是一個重要的優化參數。但也爆露出來一些問題。機器的內存愈來愈大,習慣性把參數分配的值愈來愈大。這個參數加大後也引起了一系列問題。咱們首先分析一下 query_cache_size的工做原理:一個SELECT查詢在DB中工做後,DB會把該語句緩存下來,當一樣的一個SQL再次來到DB裏調用時,DB在該表沒發生變化的狀況下把結果從緩存中返回給Client。這裏有一個關建點,就是DB在利用Query_cache工做時,要求該語句涉及的表在這段時間內沒有發生變動。那若是該表在發生變動時,Query_cache裏的數據又怎麼處理呢?首先要把Query_cache和該表相關的語句所有置爲失效,而後在寫入更新。那麼若是Query_cache很是大,該表的查詢結構又比較多,查詢語句失效也慢,一個更新或是Insert就會很慢,這樣看到的就是Update或是Insert怎麼這麼慢了。因此在數據庫寫入量或是更新量也比較大的系統,該參數不適合分配過大。並且在高併發,寫入量大的系統,建議把該功能禁掉。
(14)query_cache_limit = 4M
#指定單個查詢可以使用的緩衝區大小,缺省爲1M
(15)query_cache_min_res_unit = 2k
#默認是4KB,設置值大對大數據查詢有好處,但若是你的查詢都是小數據查詢,就容易形成內存碎片和浪費
#查詢緩存碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%
#若是查詢緩存碎片率超過20%,能夠用FLUSH QUERY CACHE整理緩存碎片,或者試試減少query_cache_min_res_unit,若是你的查詢都是小數據量的話。
#查詢緩存利用率 = (query_cache_size – Qcache_free_memory) / query_cache_size * 100%
#查詢緩存利用率在25%如下的話說明query_cache_size設置的過大,可適當減少;查詢緩存利用率在80%以上並且Qcache_lowmem_prunes > 50的話說明query_cache_size可能有點小,要不就是碎片太多。
#查詢緩存命中率 = (Qcache_hits – Qcache_inserts) / Qcache_hits * 100%
(16)thread_stack = 192K
#設置MYSQL每一個線程的堆棧大小,默認值足夠大,可知足普通操做。可設置範圍爲128K至4GB,默認爲256KB,使用默認觀察
(17)transaction_isolation = READ-COMMITTED
# 設定默認的事務隔離級別.可用的級別以下:READ UNCOMMITTED-讀未提交 READ COMMITTE-讀已提交 REPEATABLE READ -可重複讀 SERIALIZABLE -串行
(18)tmp_table_size = 256M
# tmp_table_size 的默認大小是 32M。若是一張臨時表超出該大小,MySQL產生一個 The table tbl_name is full 形式的錯誤,若是你作不少高級 GROUP BY 查詢,增長 tmp_table_size 值。若是超過該值,則會將臨時表寫入磁盤。
(18)max_heap_table_size = 256M
(19)expire_logs_days = 7
(20)key_buffer_size = 2048M
#批定用於索引的緩衝區大小,增長它能夠獲得更好的索引處理性能,對於內存在4GB左右的服務器來講,該參數可設置爲256MB或384MB。
(21)read_buffer_size = 1M
#默認128K
# MySql讀入緩衝區大小。對錶進行順序掃描的請求將分配一個讀入緩衝區,MySql會爲它分配一段內存緩衝區。read_buffer_size變量控制這一緩衝區的大小。若是對錶的順序掃描請求很是頻繁,而且你認爲頻繁掃描進行得太慢,能夠經過增長該變量值以及內存緩衝區大小提升其性能。和sort_buffer_size同樣,該參數對應的分配內存也是每一個鏈接獨享。
(22)read_rnd_buffer_size = 16M
# MySql的隨機讀(查詢操做)緩衝區大小。當按任意順序讀取行時(例如,按照排序順序),將分配一個隨機讀緩存區。進行排序查詢時,MySql會首先掃描一遍該緩衝,以免磁盤搜索,提升查詢速度,若是須要排序大量數據,可適當調高該值。但MySql會爲每一個客戶鏈接發放該緩衝空間,因此應儘可能適當設置該值,以免內存開銷過大。
(23)bulk_insert_buffer_size = 64M
#批量插入數據緩存大小,能夠有效提升插入效率,默認爲8M
(24)myisam_sort_buffer_size = 128M
# MyISAM表發生變化時從新排序所需的緩衝 默認8M
(25)myisam_max_sort_file_size = 10G
# MySQL重建索引時所容許的最大臨時文件的大小 (當 REPAIR, ALTER TABLE 或者 LOAD DATA INFILE).
# 若是文件大小比此值更大,索引會經過鍵值緩衝建立(更慢)
(26)myisam_max_extra_sort_file_size = 10G 5.6無此值設置
(27)myisam_repair_threads = 1 默認爲1
# 若是一個表擁有超過一個索引, MyISAM 能夠經過並行排序使用超過一個線程去修復他們.
# 這對於擁有多個CPU以及大量內存狀況的用戶,是一個很好的選擇.
(28)innodb_additional_mem_pool_size = 16M
#這個參數用來設置 InnoDB 存儲的數據目錄信息和其它內部數據結構的內存池大小,相似於Oracle的library cache。這不是一個強制參數,能夠被突破。
(29)innodb_buffer_pool_size = 2048M
# 這對Innodb表來講很是重要。Innodb相比MyISAM表對緩衝更爲敏感。MyISAM能夠在默認的 key_buffer_size 設置下運行的能夠,然而Innodb在默認的 innodb_buffer_pool_size 設置下卻跟蝸牛似的。因爲Innodb把數據和索引都緩存起來,無需留給操做系統太多的內存,所以若是隻須要用Innodb的話則能夠設置它高達 70-80% 的可用內存。一些應用於 key_buffer 的規則有 — 若是你的數據量不大,而且不會暴增,那麼無需把 innodb_buffer_pool_size 設置的太大了
(30)#innodb_data_file_path = ibdata1:1024M:autoextend 設置過大致使報錯,默認12M觀察
#表空間文件 重要數據
(31)#innodb_file_io_threads = 4 不明確,使用默認值
#文件IO的線程數,通常爲 4,可是在 Windows 下,能夠設置得較大。
(32)innodb_thread_concurrency = 8
#服務器有幾個CPU就設置爲幾,建議用默認設置,通常爲8.
(33)innodb_flush_log_at_trx_commit = 2
# 若是將此參數設置爲1,將在每次提交事務後將日誌寫入磁盤。爲提供性能,能夠設置爲0或2,但要承擔在發生故障時丟失數據的風險。設置爲0表示事務日誌寫入日誌文件,而日誌文件每秒刷新到磁盤一次。設置爲2表示事務日誌將在提交時寫入日誌,但日誌文件每次刷新到磁盤一次。
(34)#innodb_log_buffer_size = 16M 使用默認8M
#此參數肯定些日誌文件所用的內存大小,以M爲單位。緩衝區更大能提升性能,但意外的故障將會丟失數據.MySQL開發人員建議設置爲1-8M之間
(35)#innodb_log_file_size = 128M 使用默認48M
#此參數肯定數據日誌文件的大小,以M爲單位,更大的設置能夠提升性能,但也會增長恢復故障數據庫所需的時間
(36)#innodb_log_files_in_group = 3 使用默認2
#爲提升性能,MySQL能夠以循環方式將日誌文件寫到多個文件。推薦設置爲3M
(37)#innodb_max_dirty_pages_pct = 90 使用默認75觀察
# Buffer_Pool中Dirty_Page所佔的數量,直接影響InnoDB的關閉時間。參數innodb_max_dirty_pages_pct 能夠直接控制了Dirty_Page在Buffer_Pool中所佔的比率,並且幸運的是innodb_max_dirty_pages_pct是能夠動態改變的。因此,在關閉InnoDB以前先將innodb_max_dirty_pages_pct調小,強制數據塊Flush一段時間,則可以大大縮短 MySQL關閉的時間。
(38)innodb_lock_wait_timeout = 120
#默認爲50秒 InnoDB 有其內置的死鎖檢測機制,能致使未完成的事務回滾。可是,若是結合InnoDB使用MyISAM的lock tables 語句或第三方事務引擎,則InnoDB沒法識別死鎖。爲消除這種可能性,能夠將innodb_lock_wait_timeout設置爲一個整數值,指示 MySQL在容許其餘事務修改那些最終受事務回滾的數據以前要等待多長時間(秒數)
(39)innodb_file_per_table = 0
#默認爲No #獨享表空間(關閉)數據結構



做者:biaoqianwo
連接:https://www.jianshu.com/p/30faade8d828

併發

 

  掃二維碼,關注更多PHP資訊!函數

qrcode_for_gh_eca2f6d7a005_258.jpg

相關文章
相關標籤/搜索