開發中 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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282104.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282104.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282104.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PaddleOCR在 Linux下的webAPI部署方案

很多小伙伴在使用OCR時都希望能采用API的方式調用,這樣就可以跨端跨平臺了。本文將介紹一種基于python的PaddleOCR識別WebAPI部署方案。喜歡的可以關注公眾號,獲取更多內容。一、 Linux環境下部署1.環境要求操作系統:CenterOS7;主…

影響程序員生涯的三個錯誤觀念,你千萬不要犯!

程序員在社會上,到底是怎樣一個生活群體?是否能找到自己方向?其實,路一直都在那里,只是你看不到而已! 當初的你,可能一直被一些技術牽著鼻子走,并不是自己在做著自己想做的&#xff…

心電圖計算心率公式_心電圖到底能反應啥問題,看過之后你也能當“醫生”

只要是經歷過健康體檢的健康人,或者做過手術的患者,基本都做過心電圖檢查。都說久病成醫,所以有些人對血、尿常規等各項檢查的結果都門清兒得很,最起碼看一眼也能說出個大概齊。偏偏心電圖這種常做的檢查,不但老病號如…

獲取正在運行的服務

手機上安裝的App,在后臺運行著很多不同功能的服務,最常見的例如消息推送相關的服務。如何查看這些服務?如何判斷某個服務是否正在運行?如何停止某一個服務呢?請看下面的方法: package com.example.servicel…

openstack的vnc啟動ssl

1、制作ssl證書# cd /etc/pki/tls/certs [rootwww certs]# make vnc.key Enter pass phrase:# 輸入密碼 Verifying - Enter pass phrase:#確認# 從private key 中刪除密碼# openssl rsa -in vnc.key -out vnc.key # make vnc.csr Country Name (2 letter code) [XX]:CN# 國家 S…

開發composer包

一、初始化&#xff08;生成composer.json文件&#xff09; composer init#輸入你要創建的composer包項目命名空間 Package name (<vendor>/<name>) [root/tiny-laravel]: #haveyb/tiny-laravel #輸入composer包的描述 Description []:#this is a tiny laravel h…

Linux本地yum源配置以及使用yum源安裝gcc編譯環境

本文檔是圖文安裝本地yum源的教程&#xff0c;以安裝gcc編譯環境為例。 適用范圍&#xff1a;所有的cetos,紅帽,fedroa版本 適用人群&#xff1a;有一點linux基礎的小白 范例系統版本&#xff1a;CentOS Linux release 7.3.1611 (Core) 范例環境&#xff1a;vmware 虛擬機 安裝…

word如何設置上標形式_如何在word中設置特殊頁碼

獲取更多業界資訊和深度好文● 點擊藍字關注我們 ●在日常工作中&#xff0c;我們編輯的word文檔經常需要設置頁碼&#xff0c;但有時文檔的第一頁是封面&#xff0c;第二頁才是正文&#xff0c;或者第二頁是目錄&#xff0c;第三頁才是正文&#xff0c;如下圖所示&#xff0c;…

[cf797c]Minimal string(貪心+模擬)

題意&#xff1a; 給出了字符串s的內容&#xff0c;字符串t&#xff0c;u初始默認為空&#xff0c;允許做兩種操作&#xff1a; 1、把s字符串第一個字符轉移到t字符串最后 2、把t字符串最后一個字符轉移到u字符串最后 最后要求s、t字符串都為空&#xff0c;問u字符串字典序最小…

發布composer包到 Packagist,并設置自動同步(從github到Packagist)

一、發布composer包 1、將我們寫好的項目包發布到github上 這一步不贅述&#xff0c;應該都會。 但是需要注意的是&#xff0c;我們一定要為我們的項目包打上tag之后再提交&#xff0c;否則 我們composer require時可能會報錯 Could not find a version of package。 # 設置…

教你在CorelDRAW中導入位圖

在CorelDRAW軟件中不能直接打開位圖圖像&#xff0c;在實際操作中&#xff0c;用戶需要使用導入位圖圖像的方法進行操作。導入位圖圖像時&#xff0c;可以導入整幅圖像&#xff0c;也可以在導入的過程中對圖像進行裁剪&#xff0c;或重新取樣圖像&#xff0c;導入整幅位圖圖像時…

.NET 6 中將 ASP.NET Core 注冊成 Windows Service

前言使用 Visual Studio 中的 Worker Service項目模板:我們很容易創建出 Windows Service&#xff1a;IHost host Host.CreateDefaultBuilder(args).UseWindowsService().ConfigureServices(services >{services.AddHostedService<Worker>();}).Build();await host.R…

19.12 添加自定義監控項目 配置郵件告警 測試告警

9月12日任務19.12 添加自定義監控項目19.13/19.14 配置郵件告警19.15 測試告警19.16 不發郵件的問題處理19.12 添加自定義監控項目需求&#xff1a;監控某臺web的80端口連接數&#xff0c;并出圖兩步&#xff1a;1&#xff09;zabbix監控中心創建監控項目&#xff1b;2&#xf…

wab框架

http協議 一、http簡介 1.HTTP是一個基于TCP/IP通信協議來傳遞數據&#xff08;HTML 文件, 圖片文件, 查詢結果等&#xff09;。 2.HTTP是一個屬于應用層的面向對象的協議&#xff0c;由于其簡捷、快速的方式&#xff0c;適用于分布式超媒體信息系統。它于1990年提出&#xff0…

c++ 二維矩陣 轉vector_Python線性代數學習筆記——矩陣的基本運算和基本性質,實現矩陣的基本運算...

當學習完矩陣的定義以后&#xff0c;我們來學習矩陣的基本運算&#xff0c;與基本性質矩陣的基本運算&#xff1a;矩陣的加法&#xff0c;每一個對應元素相加&#xff0c;對應結果的矩陣例子&#xff1a;矩陣A和矩陣B表示的是同學上學期和下學期的課程的成績&#xff0c;兩個矩…

android 4.4以上能夠實現的沉浸式狀態欄效果

僅僅有android4.4以及以上的版本號才支持狀態欄沉浸效果 先把程序執行在4.4下面的手機上,看下效果: 在4.4以上的效果: 當然圖片也是能夠作為背景的.效果: 代碼: if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {Window window getWindow();window.setFlags(Wind…

為abp vnext生成C#客戶端給非abp第三方net程序使用

abp vnext提供了動態C#API客戶端和靜態C#API客戶端來調用abp項目的接口&#xff0c;但是有局限性&#xff1b;要使用動態C#API客戶端的項目必須也是ABP vnext的項目。靜態C#API客戶端也依賴abp的包&#xff0c;如下圖為的靜態客戶端依賴于 Volo.Abp.DependencyInjection、Volo.…

項目中引入composer包

假如在云服務器上&#xff0c;項目根目錄在 /data/shop&#xff0c;則 示例&#xff1a; cd /data/shop響應的結果可能會有兩種: 1、第一種是直接require成功 示例&#xff1a; composer require haveyb/tiny-laravel #響應結果 ./composer.json has been created Loading …

圓的擬合

1.三點求圓心和半徑 https://blog.csdn.net/liyuanbhu/article/details/52891868 2.最小二乘擬合圓轉載于:https://www.cnblogs.com/yhlx125/p/9671641.html

printf()函數不能直接輸出string類型

因為string不是c語言的內置數據&#xff0c;所以直接printf輸出string類型的是辦不到的。 要這樣輸出: printf("%s\n",a.c_str()); 舉例: #include<bits/stdc.h> using namespace std; int main(){string a"人生";printf("%s\n",a.c_str()…