日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

开发中 MySQL 规范

發布時間:2023/12/4 数据库 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 开发中 MySQL 规范 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、建表規范

 
1、數據庫名、表名、字段名必須使用小寫字母或數字,并且禁止以數字開頭

示例:goods_category、agent_operate_201812_log

 
?
2、數據庫名、表名、字段名要做到見名識意

示例:goods_category,不能 gc

 
?
3、配置表建議以 xx_config 形式命名

示例:shop_payment_config

 
?
4、日志表建議以 xx_log 形式命名

示例:system_log

 
?
5、臨時表建議以 temp_xx 形式命名

示例:temp_order_info_export

 
?
6、創建時間使用 create_time,更新時間使用 update_time

類型使用 int(11) unsigned

 
?
7、字段類型為字符串時需要注意的

如果存儲的字符串長度幾乎相等,則應該使用 char 定長字符串類型。

如果長度超過5000個字符,則應該將字段類型定義為 text,并獨立出來一張表,用主鍵對應,避免影響其他字段的索引效率。

 
?
8、字段允許適當冗余,以提高查詢性能,但必須考慮數據一致性

 
?
9、單表行數超過 500 萬行 或者 單表容量超過 2GB 時,才推薦進行分庫分表

 
?
10、當存儲的字段為小數時,數據類型設置為 decimal,禁止使用 float 和 double

在存儲的時候,float 和 double 存在精度損失的問題,很可能在比較值的時候,得到不正確的結果。

如果存儲的數據范圍超過 decimal 的范圍,建議將數據拆成整數和小數分開存儲。

存儲商品價格時,統一轉為分,存儲類型應為整型 int。

 
?
11、沒有特殊要求的情況下,所有的數據表必須使用 Innodb 存儲引擎

Innodb 支持事務,支持行級鎖,擁有更好的并發性能和恢復性。

 
?
12、數據庫和數據表的字符集統一使用 utf8,需要存儲 emoji 表情的使用 utf8mb4

 
?
13、所有數據表和字段必須寫 comment 注釋說明

有條件盡量建立數據字典。

 
?
14、盡量做到冷熱數據分離,減小表的寬度

表越寬,把表裝進內存緩沖池時所占用的內存也就越大,也會消耗更多的 IO。

 
?
15、禁止在數據表中建立預留字段

預留字段的命名很難做到見名識意,并且無法選擇合適的類型,而且對預留字段修改時,會對整張表進行鎖定。

 
?
16、禁止在數據庫中存儲圖片、文件等大的二進制數據

文件很大時,IO 將會很耗時,也會占用很多帶寬,影響響應速度。

建議圖片、視頻、大文件統一存儲在文件存儲空間,比如阿里云、騰訊云的對象存儲空間和文件存儲空間,數據庫中只記錄文件地址。

 
?
17、設置合適的字符存儲長度

?

對象 ?年齡區間類型 ?字節表示范圍
人 ?150歲以內unsigned tinyint1無符號值 0~255
烏龜 ?數百歲unsigned smallint2無符號值 0~65535
恐龍化石數千萬年unsigned int4無符號值 0~約42.9億
太陽 ?約50億年unsigned bigint8無符號值 0~約10^19

 
?


18、條件允許,就將字符串轉換成數字類型存儲

比如存儲ip時,使用 ip2long 和 long2ip

 
?
19、避免使用 enum 類型存儲字段

enum 類型的 orderby 操作效率低。

 
?
20、建議把所有列定義為 NOT NULL

索引 null 列需要額外的空間來保存,要占用更多空間。進行比較時和計算時要對 null 值進行特別處理。

 
?
21、禁止在開發環境、測試環境直接連接生產環境數據庫


 

 
?二、索引規范

 
1、業務上具有唯一特性的字段,即使是多個字段的組合,也必須建成唯一索引

唯一索引影響 insert 的速度可以忽略不計,但會明顯提高查詢速度。

另外,即使在應用層做了非常完善的校驗控制,只要沒有唯一索引,根據墨菲定律,必然會有臟數據產生。

 
?
2、禁止3個表以上join。需要join的字段,數據類型必須一致,當多表關聯時,保證被關聯的字段有索引


 ?
3、限制每張表上的索引數量,盡量不超過5個

索引增加查詢效率的同時,也會降低插入和更新的效率,甚至有時會降低查詢效率。

mysql優化器在選擇如何優化查詢時,會根據統一信息,對每一個可以用到的索引進行評估,以生成一個最佳的執行計劃。

如果同時有很多個索引都可以用于查詢,就會增加mysql優化器生成執行計劃的時間,進而降低查詢性能。

 
?
4、在 varchar 字段上建立索引時,必須指定索引長度

沒必要對全字段建立索引,根據實際文本區分度決定索引長度即可。一般對字符串數據,長度為20的索引,區分度就會高達 90%。

可以使用下列語句來確定區分度。

count(distinct left (列名,索引長度)) / count(*)

?

 
5、頁面搜索嚴禁左模糊或全模糊,如果需要,請使用搜索引擎解決

索引文件具有最左匹配特性,如果左邊的值未確定,則無法使用此索引。

 
?
6、如果有order by 的場景,請注意利用索引的有序性

正例:where a=5 and b=10 order by c; #索引 a_b_c 生效反例:where a>10 order by b #索引中有范圍查找,索引 a_b 不生效

 
?
7、使用延遲關聯或者子查詢優化超多分頁場景

MySQL 并不是跳過 offset 行,而是取 offset + n 行。

當 offset 特別大時,效率將會非常低,要么控制返回的總頁數,要么對超過特定閥值的頁數進行 SQL 改寫。

正例:先快速定位需要獲取的 id 段,然后再關聯。

SELECT a.* FROM 表1 a, (select id from 表1 where 條件 LIMIT 100000,20 ) b where a.id=b.id

實例對比:

select a.* from agent_admin a, (select agent_admin_id from agent_admin where admin_id = 11400 limit 1000,5 ) b where a.agent_admin_id=b.agent_admin_id; 0.017sSELECT * from agent_admin where admin_id = 11400 limit 1000,5; 0.023S

 
?
8、建立組合索引時,區分度最高的放在最左邊

 
?
9、哪些字段最好建索引

(1)經常出現在 where 從句的字段

(2)包含在 order by,group by、distinct 中的字段

 
?
10、避免建立重復索引和冗余索引

建立冗余索引,ui增加查詢優化器生成執行計劃的時間

// 重復索引示例 primary key(id) index(id) unique key(id) // 冗余索引示例 index(a,b,c) index(a,b) index(a)


 
?
11、創建索引時盡量避免如下誤解

(1)寧濫勿缺:認為一個查詢就需要建立一個索引

(2)寧缺毋濫:任務索引會消耗空間、嚴重拖慢更新和新增速度

(3)抵制唯一索引:認為業務的唯一性一律需要在應用層通過“先查后插”的方式解決


 

 
三、SQL 開發規范

 
?
1、不要使用 count(列名) 或 count(常量) 來替代 count(\*)

count(\*) 是 SQL92 定義的標準統計行數的語法,count(\*) 會統計值為NULL的行,而count(列名) 不會統計此列值為 null 的行。

 
2、在代碼中寫分頁查詢邏輯時,如果 count 為 0 ,應直接返回結果,避免繼續執行后面的程序再返回結果

 
?
3、禁止使用存儲過程

存儲過程難以調試和擴展,新人接手麻煩,可移植性差。

 
?
4、禁止使用外鍵與級聯,一切外鍵概念必須在應用層解決

以學生和成績的關系為例,學生表中的student_id是主鍵,那么成績表中的student_id則為外鍵。如果更新學生表中的 student_id,同時觸發成績表中的student_id更新,即為級聯更新。

外鍵與級聯更新適用于單機低并發,不適合分布式、高并發集群;

級聯更新是強阻塞,存在數據庫更新風暴的風險;外鍵影響數據庫的插入速度。

 
?
5、建議使用預編譯語句進行數據庫操作

盡量使用框架自帶的查詢構造器,其底層均封裝了預編譯處理。如果特殊情況使用不了框架的查詢構造器,也要手動預編譯查詢。

預編譯語句可以重復使用優化查詢器生成的執行計劃,減少 SQL編譯 所需要的時間,還可以解決動態 SQL 所帶來的的 SQL 注入問題。

 
?
6、避免數據類型的隱式轉換

select user_name,age from admin where admin_id = '11140';

 
?
7、禁止使用 select \*,必須指定要查詢的具體字段


(1)無法使用覆蓋索引

注:覆蓋索引的含義是 select 的數據列只從索引中就能夠取得,不必讀取數據行,換句話說查詢列已經被所建的索引覆蓋。

(2)消耗更多的 cpu 和 IO 以及網絡帶寬資源。

 
?
8、避免使用子查詢,可以把子查詢優化成join查詢

子查詢的結果集無法使用索引,通常子查詢的結果集會被存儲到臨時表中,不論是內存臨時表還是磁盤臨時表都不會存在索引,所以查詢性能會受到一定的影響。特別是對于返回結果集比較大的子查詢,其對查詢性能的影響也就越大。

注:通常子查詢在in子句中,并且子查詢中為簡單SQL(不包含union、group by、order by、limit從句)時,才可以把子查詢轉化為關聯查詢進行優化。

 
?
9、避免使用JOIN關聯太多的表

對于Mysql來說,是存在關聯緩存的,緩存的大小可以由join_buffer_size參數進行設置。

在 Mysql 中,對于同一個 SQL 多關聯一個表,就會多分配一個關聯緩存,在一個SQL 中,關聯的表越多,所占用的內存就越大。

如果程序中大量的使用了多表關聯的操作,同時 join_buffer_size 設置的也不合理的情況下,就容易造成服務器內存溢出的情況,進而影響到服務器數據庫性能的穩定性。

MySQL 最多允許關聯61個表,建議不超過5個

 
?
10、減少和數據庫的交互操作

合并多個相同的操作到一起,可以提高處理效率。比如批量更新時,將語句處理合并后,在提交到 MySQL 中進行處理,這樣效率會更高。

一定要避免在循環中執行 SQL。

 
?
11、對同一列進行 or 判斷時,使用 in 代替 or

舉例:

select user_name,age from admin where city in (1024, 1028);

in 操作可以更有效的利用索引,or 大多數情況下很少能利用到索引。但需要注意的是,in 的值不要超過500個。

 
?
12、禁止在 SQL 語句中進行函數轉換和計算

將數據取出來再在程序中進行處理,比如格式化時間和轉換ip時。

 
?

13、在明顯不會有重復值時使用 UNINON ALL,而不是 UNION

UNION 會把兩個結果集的所有數據放到臨時表,再進行去重操作

UNINON ALL不會再對結果集進行去重操作

 
?
14、拆分復雜的大 SQL 為多個小 SQL

SQL 拆分后可以通過并行執行來提高處理效率。

 
?
15、大批量操作分批執行

大批量修改數據,會造成表中大量數據行被鎖定,從而造成大量的阻塞。

長時間的阻塞會占滿數據庫所有的可用連接,使生產環境中的其他應用無法連接到數據庫。

因此一定要注意大批量寫操作一定要分批執行。

?

原文鏈接:https://www.haveyb.com/article/149

總結

以上是生活随笔為你收集整理的开发中 MySQL 规范的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。