mysql 標準

1、數據庫命名規範,統一:vip_xxxx

0、表一旦設計好,字段只允許增加,不允許減少(drop column)

1、統一使用INNODB存儲引擎,UTF8編碼(整個數據庫的編碼統一爲utf8_general_ci,爲此不需要建立表的DDL加上特別CHARACTER SET utf8 COLLATE utf8_general_ci);

2、需在設計階段考慮如果訪問量非常大,且不做scale out表拆分的話,需讀寫分離,但讀寫分離注意主從複製有延遲的可能性;

3、禁用Stored procedure (包括存儲過程,函數,觸發器);

4、UUID(),USER()這樣的MYSQL INSIDE函數對於複製來說是很危險的,會導致主備數據不一致,重要的是會嚴重影響mysql性能,禁止使用

5、表必須有主鍵,建議統一由Auto-Increment字段生成整型,不建議使用組合主鍵,自增id只作爲虛擬主鍵,不建議與業務數據處理有關聯關係,如果把控不好,會有問題(案例:AUTO_INCREMENT主鍵字段不要與業務有關聯關係

6、庫名、表名、字段名、索引名必須使用小寫字母;

7、多表join的時候,寫SQL的時候一定要給每個字段指定表名做前綴;如: select a.id,a.name from test1 a, test2 b where a.id=b.id

8、如果應用使用的是長連接,應用必須具有自動重連的機制。但請避免每執行一個SQL去檢查一次DB可用性;

9、如果應用使用的是長連接,應用應該具有連接的TIMEOUT檢查機制,及時回收長時間沒有使用的連接,TIMEOUT時間一般建議爲20min。

10、存儲精確浮點數必須使用DECIMAL替代FLOAT和DOUBLE,如金額等。

11、儘量用單表查詢,避免多表JOIN。

12、表名列名必須有註釋(必須加上COMMENT '<字段扼要解說>'),表結構變更須由庫表OWNER所在團隊發起,

13、SQL語句必須採用preparedStatement技術, 如果編程語言不支持preparedStatement技術,需要做好特殊字符過濾,如不要前後有空串等

14、儘可能不要使用TEXT、BLOB、char,請使用VARCHAR(N),N表示的是字符數不是字節數,比如VARCHAR(255),可以最大可存儲255個漢字,需要根據實際的寬度來選擇N,請注意同一表中,所有varchar字段的長度加起來,不能大於65535。

15、每張表數據量建議控制在千萬級別行以下,爲此設計階段需考慮數據的歸檔。

16、如果字段只有true or false,請使用tinyint(數值範圍-128~127),如模塊分類:1訂單 2商品;刪除標誌 0正常,1刪除;狀態 1爲可選,2爲不可選等等

17、存儲時間(精確到秒)建議使用TIMESTAMP類型,因爲TIMESTAMP使用4字節,DATETIME使用8個字節,同時TIMESTAMP具有自動賦值以及自動更新的特性。

18、每個字段的默認值不能用NULL,禁止default NULL,數字類型default 0,字符類型default '';

19、關鍵業務數據表,建議有create_time和last_update_time,方便後期數據分析,如訂單表,庫存表;

20、MySQL上,禁止使用select col、col from table where id in (select col from table)這樣的子查詢;

21、需要多表join的字段(禁止多於兩表join),數據類型保持絕對一致。

22、關鍵業務數據表,如訂單表,用戶信息表,錢包支付信息等,禁止硬刪除,必須軟刪除,加上is_deleted字段,標註這條記錄的狀態。

23、加字段禁止使用after,因爲你不確定全局代碼裏面(如其他團隊使用你的表)是否都insert into table(col,col,col。。。) value,如果你在中間插一個字段,就導致數據偏移的問題了,影響可大可小,同樣select * 的也可能會影響數值的偏移,所以纔要求,禁止after,必須帶default(第18點要求)。

24、線上MySQL是忽略大小寫的(配置了lower_case_table_names=1),如下面的例子:

 

 

 

事務的處理標準

0、一個事務,處理的行數不能超過1000 rows/s (曾經發生過的案例,超出了會導致主從複製延遲的問題

1、禁止一些框架或定製化的底層類等使用set autocommit=0;set autocommit=1;這樣控制事務,應該由程序把控,需要時begin;操作完後及時commit2、要合理使用事務,例子:購物車如下的 事務處理,可以更好的優化。

 

下面的事務可以更好的優化,start transection後,select 1次,insert 2次,seletc 1次,update 1次,總:2 QPS,3 TPS,然後沒有庫存 rollback,這種在正常情況下沒有問題的,按如小米這種極端搶購的情況下,會大大浪費了購物車數據庫的CPU資源
########################################################
#如用戶ID:72965761,一次事務的操作
########################################################
Query SET NAMES utf8
Query start transaction
Query SELECT `cart`.`id`, `cart`.`user_id`, `cart`.`warehouse`, `cart`.`add_time`, `cart`.`expire_time`, `cart`.`add_type` FROM `cart` WHERE (user_id =72965761 OR user_id=-72965761) AND (warehouse = 'VIP_NH') AND (expire_time >= 1408084591) ORDER BY `id` DESC LIMIT 1
Query INSERT IGNORE INTO `cart` (`user_id`, `warehouse`, `add_time`, `expire_time`, `add_type`) VALUES (72965761, 'VIP_NH', 1408084591, 1408085791, 0)
Query INSERT IGNORE INTO `user_cart` (`cart_id`, `user_id`, `product_id`, `size`, `num`, `add_time`, `warehouse`, `product_info`, `brand_id`, `suite_id`, `active_id`, `active_limit_id`, `active_no`, `add_type`) VALUES (442034, 72965761, '30014072', '78845863', '1', 1408084591, 'VIP_NH', '', '210123', 0, 0, 0, '', 0)
Query SELECT `user_cart`.`id` FROM `user_cart` WHERE (cart_id = 442034 AND flag = '0')
Query UPDATE `user_cart` SET `add_time` = 1408084591 WHERE id in ('711744') AND flag = '0'
Query rollback
Quit

 

索引使用標準

 

1、非唯一索引建議使用“idx_表縮寫名稱_字段縮寫名稱”進行命名。

2、唯一索引建議使用“uniq_表縮寫名稱_字段縮寫名稱”進行命名。

3、索引名稱必須使用小寫。

4、唯一鍵不和主鍵重複。

5、索引字段的順序需要考慮字段值去重之後的個數,個數多的放在前面,就是數據分佈。

6、使用EXPLAIN判斷SQL語句是否合理使用索引,儘量避免extra列出現:Using File Sort,Using Temporary。

7、UPDATE、DELETE語句需要根據WHERE條件添加索引。

8、合理創建聯合索引(避免冗餘),(a,b,c) 相當於 (a) 、(a,b) 、(a,b,c)。

9、合理利用覆蓋索引。比如SELECT email,uid FROM user_email WHERE uid=xx,如果uid不是主鍵,適當時候可以將索引添加爲index(uid,email),以獲得性能提升。

 

 

 

約束設計

a) 主鍵的內容不能被修改。

b) 外鍵約束一般不在數據庫上創建,只表達一個邏輯的概念,由程序控制。

d) 禁用數據庫外鍵

命名

a) 主鍵約束:默認PRIMARY;

b) unique約束:UK_<column_name>

c) check約束: CK_<column_name>

d) 外鍵約束: 業務禁用

 

 

SQL語句標準

 

0、禁止多於3表的join。

1、使用prepared statement,可以***能並且避免SQL注入。

2、SELECT語句只獲取需要的字段,禁止使用SELECT * FROM語句,這是有效防止新增字段對應用邏輯的影響,還能減少對性能的影響;

3、INSERT語句必須顯式的指明字段名稱,不使用INSERT INTO table value()。

4、禁止在where子句中對字段施加函數,如to_date(add_time)>xxxxx,應改爲:add_time >= unix_timestamp(date_add(str_to_date('20130227','%Y%m%d'),interval - 29 day))

5、UPDATE、DELETE語句不使用LIMIT。

6、寫到應用程序裏的SQL語句,禁止一切DDL操作,如對這些權限有要求,必需與DBA協商同意方可使用

7、WHERE條件中必須使用合適的類型,避免MySQL進行隱式類型轉化,如ISENDED=1,字段類型是tinyint,那麼不能是ISENDED=‘1’。

8、避免在SQL語句進行數學運算或者函數運算,容易將業務邏輯和DB耦合在一起。

9、INSERT語句使用batch提交。

10、避免使用存儲過程、觸發器、函數等,容易將業務邏輯和DB耦合在一起,並且MySQL的存儲過程、觸發器、函數中存在一定的bug。

11、使用合理的SQL語句減少與數據庫的交互次數。

12、不使用ORDER BY RAND(),使用其他方法替換。

13、建議使用合理的分頁方式以提高分頁的效率。

14、InnoDB表避免使用COUNT(*)操作,計數統計實時要求較強可以使用memcache或者redis,非實時統計可以使用單獨統計表,定時更新。

15、不建議使用%前綴模糊查詢,例如LIKE “%weibo”。

16、避免多餘的排序。使用GROUP BY 時,默認會進行排序,當你不需要排序時,可以使用order by null,例如Select a.OwnerUserID,count(*) cnt from DP_MessageList a group by a.OwnerUserID order by null;

 

  

 

每個整數類型的存儲和範圍。

 

類型

字節

最小值

最大值

(帶符號的/無符號的)

(帶符號的/無符號的)

TINYINT

1

-128

127

0

255

SMALLINT

2

-32768

32767

0

65535

MEDIUMINT

3

-8388608

8388607

0

16777215

INT

4

-2147483648

2147483647

0

4294967295

BIGINT

8

-9223372036854775808

9223372036854775807

0

18446744073709551615

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章