數據庫設計規範

1、數據庫設計規範(設計之初,須要DBA介入)mysql

規範前言:redis

1.保證數據庫高可用:制定3重高可用(容災)架構,主備架構、同城容災、異地容災(能夠採用mha、pxc等高可用架構,注意數據可能丟失風險)sql

2.根據業務瞭解熱點數據:制定相應熱點數據是否須要redis等緩存,來減小直接對數據庫訪問的請求,以及根據不一樣狀況制定相應的redis與mysql的數據同步機制,若是選擇redis,則可採用哨兵或cluster高可用架構數據庫

3.根據業務瞭解數據分佈及讀寫狀況:制定是否須要分庫分表及讀寫分離,以及此策略對應採用哪一種中間件緩存

4.根據業務瞭解數據分析對應數據需求:制定是否須要採用不影響生產庫性能的同時,經過binlog進行實時同步數據來作數據分析服務器

5.根據業務對數據保留需求:制定相應的備份策略,並制定按期備份驗證策略架構

6.根據業務瞭解活躍dml相關表:制定按期整理分析表策略併發

7.根據業務瞭解大表數據留存需求:制定歷史數據的清理機制數據庫設計

8.部署夜鷹:對數據庫服務器進行合理監控,能夠採用zabbix、pmm、openfalcon等監控工具函數

9.不在數據庫作運算:cpu計算移至業務層

10.控制單表數據量:單表記錄控制在1000w

11.控制列數量:字段數控制在20之內

12.平衡範式與反範式:爲提升效率犧牲範式設計,冗餘數據

13.拒絕3B:拒絕大sql,大事物,大批量




表設計規範:

1.庫名、表名、字段名儘可能使用小寫字母,"_"分割。

2.庫名、表名、字段名儘可能不超過26個字符。

3.庫名、表名、字段名見名知其意,建議使用名詞而不是動詞。

4.非惟一索引按照「idx_表簡寫_字段簡寫」命名。

5.惟一索引必須按照「uniq_表簡寫_字段簡寫」命名。

7.每張表及每一個字段必須有註釋。

8.mysql建議使用innodb爲默認存儲引擎,建表採用默認存儲引擎便可。

9.字符集建議默認採用utf8或utf8mb4(mysql5.7),表使用默認字符集便可。

10.innodb表必定要有主鍵,在不分庫分表的狀況下,不要使用有實際意義的字段作主鍵,且隨機主鍵索引,插入致使大量的頁面分割,建議使用自增id,儘可能不要使用聯合主鍵,長主鍵索引使全部相應的二級索引變得更長、更慢(注意:主鍵創建聚簇索引、主鍵不該該被修改、字符串不該該作主鍵、若是不指定主鍵,innodb會使用惟一且非空值索引代替)。

固然,若是一個字段有助於在各個方面的數據分組或者這個字段被頻繁的在查詢中使用,能夠做爲主鍵。

11.建議不要採用外鍵,儘可能程序端實現其邏輯來保證約束。

12.存儲精確數值必須使用decimal,禁止使用float和double。

13.建議使用unsigned存儲非負數值。

14.整形定義中不添加長度,如int,而不是int(8)

15.varchar(n),n表示的是字符數而不是字節數,如varchar(100),能夠最大存儲100個漢字,須要根據實際須要的寬度來選擇n。

16.存儲日期建議使用date、DATETIME類型。

17.須要 join 的字段,數據類型兩邊保持絕對一致。 不一致會有隱式轉換的風險。

18.儘可能的瞭解數據類型,會運算的能用int的不用string,即使如此,也要選擇合適的int類型達到更快的查詢或運算。

19.在設計時建議包含兩個日期字段:created_time(建立日期),updated_time(修改日期)且非空。

20.儘量使用簡單數據類型,不要使用如blob、clob、long等大字段類型。

21.不容許字段默認null,能夠採用如0、一、""等


字段類型設計規範:

1.用好數值類型,最小化規則

tinyint(1Byte)、smallint(2Byte)、mediumint(3Byte)、int(4Byte)、bigint(8Byte)

不該該採用的用法:int(1)/int(11)

2.字符轉化爲數字

用int而不是char(15)存儲ip

3.優先使用enum或set

如:`sex` enum (‘F’, ‘M’)

4.避免使用NULL字段

NULL字段很難查詢優化、NULL字段的索引須要額外空間、NULL字段的複合索引無效

錯誤如:`name` char(32) default null

正確如:`age` int not null default 0

5.少用text/blob

varchar的性能會比text高不少,實在避免不了blob,請拆表

6.不在數據庫裏存圖片,應使用專門的圖片處理方式



索引設計規範:(索引是一把雙刃劍,謹慎合理使用索引,索引改善查詢、減慢更新,索引必定不是越多越好,能不加就不加,要加的必定得加,要衡量好索引帶來的收益與損耗)

1.只使用普通索引或惟一索引,其餘須要DBA參與衡量,如一些字符字段建前綴索引。

2.索引名稱必須使用小寫

3.非惟一索引按照「idx_表簡寫_字段簡寫」命名。

4.惟一索引必須按照「uniq_表簡寫_字段簡寫」命名。

5.索引中的字段數建議不要超過5個,索引是昂貴的,更新索引經常是數據庫寫操做的主要開銷,爲關鍵性能查詢集創建索引,總體取審視,而不是一個個看,最好全部的查詢條件和聯表條件都使用索引(起碼區分度最高的部分是)。

6.修改索引時,切記驗證對性能的影響。

7.不要建立冗餘或者無效的索引,如(a),(a,b)建立索引屬於重複索引。

8.多數狀況下,聯合索引比添加一個新的索引要好,固然要衡量利弊,作出取捨,注意:創建聯合索引要按能支持更多查詢的順序創建索引,把全部都是點查詢的字段放到索引的首位,

9.在聯合索引中,MySQL在遇到返回查詢(<,>,BETWEEN)條件時,將中止停止剩餘部分索引的使用;可是使用IN(…)的範圍查詢則能夠繼續往右使用索引。

10.儘可能使用索引進行排序,不使用索引將進行很是昂貴的filesort操做(external sort),經常使用聯合索引進行高效排序(注意:不能對兩個字段進行不一樣順序的排序,對非ORDER BY部分的字段只能使用點查詢(=),IN()也不行)。

11.索引能夠幫助優化 MIN()/MAX() 這類的統計函數,如:SELECT MAX(ID) FROM tab;使用key(a)

SELECT MAX(b) FROM tab GROUP BY a;使用KEY(a,b)

12.MySQL使用嵌套循環(Nested Loops)進行聯表查詢(小結果集驅動大的結果集),使每一個關聯的表(關聯字段)都使用上索引顯得很是的重要,小表(驅動表)關聯字段索引多是沒必要要的,但大表(被驅動表)關聯字段索引是必要的。

13.不要建立過多的索引,儘可能不要添加非性能關鍵查詢的索引,太多的索引會使MYSQL慢下來,如一個表超過10個以上索引,可能會影響dml的性能(5%左右),一些狀況會致使應用程序相應dml很是慢。

14.不在索引作列運算。

15.常見的不合適的索引:

a.過於理想,索引過寬,致使索引維護代價高,併發dml高了以後會出現性能抖動。

b.索引篩選性不強,走上索引也不夠快,併發高了以後對db衝擊很大。

c.並非全部索引都比全表掃描快,若是獲取的數據超過30%,則不走索引,若是超過20%,則可能走全表更好。


sql開發規範:

1.在代碼中不容許出現任何ddl語句,ddl統一由dba執行。

2.除非特殊狀況,sql語句必定要加上where條件或limit。

3.不容許寫select * from 這樣的代碼,必定要指定須要的字段,來減小無用數據的查詢請求(消耗多餘cpu,io,內存,帶寬)。

4.慎用count(*),如大概查看錶數據量,能夠經過統計信息查看,如查具體,能夠採用count(主鍵id)。

5.儘可能避免在where子句中對字段使用函數或表達式,且字段的值必定要與字段類型匹配,不然會致使索引失效。

6.有錶鏈接時,設計的時候要儘可能使兩個表的相應字段類型一致,若是不一致,則必須在一邊加上類型轉換函數(注意mysql的日期和字符是相同的,因此不須要另外的轉換)。

7.全模糊查詢沒法使用索引,應儘可能避免,如%a%,可使用半模糊查詢a%。

8.sql中直接使用表名,不使用schema做爲前綴,應在鏈接時直接連到改schema或採用use。

9.sql語句儘量簡單,不要使用複雜sql,複雜邏輯儘可能在代碼中實現(一條sql只能在一個cpu運算,大語句拆小語句,減小鎖時間,一條大sql能夠堵死整個庫)。

10.簡單的事務,使事務時間儘量短,避免如上傳圖片等事務。

11.原則上通常禁止使用<>、!=和not in,而應該轉換成相應的=和in查詢條件,若有特殊須要沒法完成相應的轉換,必須徵求dba。

12.原則上通常不容許使用exists和not exists查詢,應轉換爲相應的等鏈接和外鏈接來查詢,若有特殊須要沒法完成相應的轉換,必須徵求dba。

13.不要有太多的join,核心操做表儘可能不要join,join控制在3個之內,讓每一個查詢sql儘可能簡潔和高性能。

14.全部非外鏈接sql(inner join),把關聯表統一寫到from子句裏面,關聯條件和過濾條件統一寫到where子句中。

15.出於代碼可讀性,全部的外鏈接sql語句,統一使用left join。

16.Query語句中的ORDER BY、GROUP BY的時候,儘量利用已有的索引來避免實際的排序計算,能夠很大幅度的提高ORDER BY、GROUP BY操做的性能。

17.避免使用trig/func,由客戶端程序取而代之。

18.OR改寫爲IN(),or的效率是n級別,in的效率是log(n)級別,in的個數建議控制在200之內。

如:select id from t where a=1 or a= 2;

=>select id from t where a in (1, 2);

19.OR改寫爲UNION,mysql的索引合併不太友好

如:select id from t where a = 1 or b = 'ds';key(a),key(b)

=>select id from t where a = 1

union all或union(看具體狀況,union有去重開銷)

select id from t where b= 'jonh'


20.使用load data導數據,load data比insert快約20倍,但要注意自增主鍵問題致使主從不一致與空洞問題;

21.應用程序端儘可能採用Prepared Statements(是一種運行在後臺的SQL語句集合),在性能方面,當一個相同的查詢被使用屢次的時候,會帶來可觀的性能優點



數據庫權限分配規範


生產庫:

DBA:有全部權限,超級管理員權限

應用程序:分配insert、delete、update、select、execute、events、jobs權限。

測試人員:無權限

開發人員:無權限

原則:全部對線上表的操做,除了應用程序以外,都必須經由DBA來決定是否執行、已經何時執行等。



測試庫:

DBA:全部權限。

測試人員:有insert、delete、update、select、execute、jobs,ddl等權限。

數據分析人員:只有select查詢權限

開發人員:有select權限。

原則:DBA有全部權限,並且嚴格控制表結構的變動,不容許除了qa以外的人對測試環境的庫環境進行修改,以避免影響測試人員測試。全部對測試庫的表結構進行的修改必須由測試人員和DBA一塊兒審覈事後才能操做。


開發庫:

DBA:全部權限

測試人員:有庫表結構以及數據的全部操做權限。

開發人員:有庫表結構以及數據的全部操做權限。

數據分析人員:有庫表結構以及數據的全部操做權限。

相關文章
相關標籤/搜索