1. 程式人生 > >阿里java開發規範(6)---MySQL資料庫

阿里java開發規範(6)---MySQL資料庫

五、 MySQL 資料庫

()建表規約
1. 【強制】表達是與否概念的欄位,必須使用 is_xxx 的方式命名,資料型別是 unsigned tinyint
1 表示是, 0 表示否)。
說明: 任何欄位如果為非負數,必須是 unsigned
注意: POJO 類中的任何布林型別的變數,都不要加 is 字首,所以,需要在<resultMap>設定
is_xxx Xxx 的對映關係。資料庫表示是與否的值,使用 tinyint 型別,堅持 is_xxx
命名方式是為了明確其取值含義與取值範圍。
正例: 表達邏輯刪除的欄位名 is_deleted1 表示刪除, 0 表示未刪除。
2.
【強制】表名、欄位名必須使用小寫字母或數字禁止出現數字開頭,禁止兩個下劃線中間只
出現數字。資料庫欄位名的修改代價很大,因為無法進行預釋出,所以欄位名稱需要慎重考慮。
說明: MySQL Windows 下不區分大小寫,但在 Linux 下預設是區分大小寫。因此,資料庫名、
表名、欄位名,都不允許出現任何大寫字母,避免節外生枝。
正例: aliyun_adminrdc_configlevel3_name
反例: AliyunAdminrdcConfiglevel_3_name
3. 【強制】表名不使用複數名詞。
說明: 表名應該僅僅表示表裡面的實體內容,不應該表示實體數量,對應於 DO
類名也是單數
形式,符合表達習慣。
4. 【強制】禁用保留字,如 descrangematchdelayed 等, 請參考 MySQL 官方保留字。
5. 【強制】 主鍵索引名為 pk_欄位名; 唯一索引名為 uk_欄位名普通索引名則為 idx_欄位名。
說明: pk_ primary keyuk_ unique keyidx_ index 的簡稱。
6. 【強制】小數型別為 decimal,禁止使用 float double
說明: float double 在儲存的時候,存在精度損失的問題,很可能在值的比較時,得到不
正確的結果。如果儲存的資料範圍超過
decimal
的範圍,建議將資料拆成整數和小數分開儲存。
7. 【強制】如果儲存的字串長度幾乎相等,使用 char 定長字串型別。
8. 【強制】 varchar 是可變長字串,不預先分配儲存空間,長度不要超過 5000,如果儲存長
度大於此值,定義欄位型別為
text,獨立出來一張表,用主鍵來對應,避免影響其它欄位索
引效率。
9. 【強制】表必備三欄位: id, gmt_create, gmt_modified
說明: 其中 id 必為主鍵,型別為 bigint unsigned、單表時自增、步長為 1gmt_create,
gmt_modified
的型別均為 datetime 型別,前者現在時表示主動建立,後者過去分詞表示被
動更新。

10. 【推薦】表的命名最好是加上業務名稱_表的作用
正例: alipay_task / force_project / trade_config
11. 【推薦】庫名與應用名稱儘量一致。
12. 【推薦】如果修改欄位含義或對欄位表示的狀態追加時,需要及時更新欄位註釋。
13. 【推薦】欄位允許適當冗餘,以提高查詢效能,但必須考慮資料一致。冗餘欄位應遵循:
1不是頻繁修改的欄位。
2不是 varchar 超長欄位,更不能是 text 欄位。
正例: 商品類目名稱使用頻率高,欄位長度短,名稱基本一成不變,可在相關聯的表中冗餘存
儲類目名稱,避免關聯查詢。
14. 【推薦】單錶行數超過 500 萬行或者單表容量超過 2GB,才推薦進行分庫分表。
說明: 如果預計三年後的資料量根本達不到這個級別,請不要在建立表時就分庫分表。
15. 【參考】合適的字元儲存長度,不但節約資料庫表空間、節約索引儲存,更重要的是提升檢
索速度。
正例: 如下表,其中無符號值可以避免誤存負數, 且擴大了表示範圍。
150 歲之內 tinyint unsigned 1 無符號值: 0 255
數百歲 smallint unsigned 2 無符號值: 0 65535
恐龍化石 數千萬年 int unsigned 4 無符號值: 0 到約 42.9
太陽 50 億年 bigint unsigned 8 無符號值: 0 到約 10 19 次方

()索引規約
1. 【強制】業務上具有唯一特性的欄位,即使是多個欄位的組合,也必須建成唯一索引。
說明: 不要以為唯一索引影響了 insert 速度,這個速度損耗可以忽略,但提高查詢速度是明
顯的
另外,即使在應用層做了非常完善的校驗控制,只要沒有唯一索引,根據墨菲定律,必
然有髒資料產生。
2. 【強制】超過三個表禁止 join。需要 join 的欄位,資料型別必須絕對一致多表關聯查詢時,
保證被關聯的欄位需要有索引。
說明: 即使雙表 join 也要注意表索引、 SQL 效能。
3. 【強制】在 varchar 欄位上建立索引時,必須指定索引長度,沒必要對全欄位建立索引,根據
實際文字區分度決定索引長度即可。

說明: 索引的長度與區分度是一對矛盾體,一般對字串型別資料,長度為 20 的索引,區分
度會高達
90%以上,可以使用 count(distinct left(列名, 索引長度))/count(*)的區分度
來確定。
4. 【強制】頁面搜尋嚴禁左模糊或者全模糊,如果需要請走搜尋引擎來解決。
說明: 索引檔案具有 B-Tree 的最左字首匹配特性,如果左邊的值未確定,那麼無法使用此索
引。
5. 【推薦】如果有 order by 的場景,請注意利用索引的有序性order by 最後的欄位是組合
索引的一部分,並且放在索引組合順序的最後,避免出現
file_sort 的情況,影響查詢效能。
正例: where a=? and b=? order by c; 索引: a_b_c
反例: 索引中有範圍查詢,那麼索引有序性無法利用,如: WHERE a>10 ORDER BY b; 索引
a_b 無法排序。
6. 【推薦】利用覆蓋索引來進行查詢操作, 避免回表。
說明: 如果一本書需要知道第 11 章是什麼標題,會翻開第 11 章對應的那一頁嗎?目錄瀏覽
一下就好,這個目錄就是起到覆蓋索引的作用。
正例: 能夠建立索引的種類分為主鍵索引、唯一索引、普通索引三種,而覆蓋索引只是一種查
詢的一種效果,用
explain 的結果, extra 列會出現: using index
7. 【推薦】利用延遲關聯或者子查詢優化超多分頁場景。
說明: MySQL 並不是跳過 offset 行,而是取 offset+N 行,然後返回放棄前 offset 行,返回
N 行,那當 offset 特別大的時候,效率就非常的低下,要麼控制返回的總頁數,要麼對超過
特定閾值的頁數進行
SQL 改寫。
正例: 先快速定位需要獲取的 id 段,然後再關聯:
SELECT a.* FROM 1 a, (select id from 1 where 條件 LIMIT 100000,20 ) b where a.id=b.id
8. 【推薦】 SQL 效能優化的目標:至少要達到 range 級別, 要求是 ref 級別, 如果可以是 consts
最好。
說明:
1consts 單表中最多隻有一個匹配行主鍵或者唯一索引,在優化階段即可讀取到資料。
2ref 指的是使用普通的索引normal index
3range 對索引進行範圍檢索。
反例: explain 表的結果, type=index,索引物理檔案全掃描,速度非常慢,這個 index
別比較
range 還低,與全表掃描是小巫見大巫。
9. 【推薦】建組合索引的時候,區分度最高的在最左邊。
正例: 如果 where a=? and b=? , 如果 a 列的幾乎接近於唯一值,那麼只需要單建 idx_a
索引即可。
說明: 存在非等號和等號混合時,在建索引時,請把等號條件的列前置。如: where c>? and
d
=? 那麼即使 c 的區分度更高,也必須把 d 放在索引的最前列, 即索引 idx_d_c
10. 【推薦】 防止因欄位型別不同造成的隱式轉換, 導致索引失效。
11. 【參考】建立索引時避免有如下極端誤解:
1寧濫勿缺。 認為一個查詢就需要建一個索引。
2寧缺勿濫。 認為索引會消耗空間、嚴重拖慢更新和新增速度。
3抵制惟一索引。 認為業務的惟一性一律需要在應用層通過先查後插方式解決。
()SQL 語句
1. 【強制】不要使用 count(列名)count(常量)來替代 count(*)count(*)SQL92 定義的
標準統計行數的語法,跟資料庫無關,跟
NULL 和非 NULL 無關。
說明: count(*)會統計值為 NULL 的行,而 count(列名)不會統計此列為 NULL 值的行。
2. 【強制】 count(distinct col) 計算該列除 NULL 之外的不重複行數, 注意 count(distinct
col
1, col2) 如果其中一列全為 NULL,那麼即使另一列有不同的值,也返回為 0
3. 【強制】當某一列的值全是 NULL 時, count(col)的返回結果為 0,但 sum(col)的返回結果為
NULL,因此使用 sum()時需注意 NPE 問題。
正例: 可以使用如下方式來避免 sum NPE 問題: SELECT IF(ISNULL(SUM(g)),0,SUM(g))
FROM table;
4. 【強制】使用 ISNULL()來判斷是否為 NULL 值。
說明: NULL 與任何值的直接比較都為 NULL
1NULL<>NULL 的返回結果是 NULL, 而不是 false
2NULL=NULL 的返回結果是 NULL, 而不是 true
3NULL<>1 的返回結果是 NULL,而不是 true
5. 【強制】 在程式碼中寫分頁查詢邏輯時,若 count 0 應直接返回,避免執行後面的分頁語句。
6. 【強制】不得使用外來鍵與級聯,一切外來鍵概念必須在應用層解決。
說明: 以學生和成績的關係為例, 學生表中的 student_id 是主鍵,那麼成績表中的 student_id
則為外來鍵。如果更新學生表中的 student_id,同時觸發成績表中的 student_id 更新, 即為
級聯更新。外來鍵與級聯更新適用於單機低併發,不適合分散式、高併發叢集
級聯更新是強阻
塞,存在資料庫更新風暴的風險
外來鍵影響資料庫的插入速度。
7. 【強制】禁止使用儲存過程,儲存過程難以除錯和擴充套件,更沒有移植性。
8. 【強制】資料訂正(特別是刪除、 修改記錄操作) 時,要先 select,避免出現誤刪除,確認
無誤才能執行更新語句。
9. 【推薦】 in 操作能避免則避免,若實在避免不了,需要仔細評估 in 後邊的集合元素數量,控
制在
1000 個之內。
10. 【參考】 如果有國際化需要,所有的字元儲存與表示,均以 utf-8 編碼,注意字元統計函式
的區別。
說明:
SELECT LENGTH("輕鬆工作")返回為 12
SELECT CHARACTER_LENGTH("輕鬆工作")返回為 4
如果需要儲存表情,那麼選擇 utf8mb4 來進行儲存,注意它與 utf-8 編碼的區別。
11. 【參考】 TRUNCATE TABLE DELETE 速度快,且使用的系統和事務日誌資源少,但 TRUNCATE
無事務且不觸發 trigger,有可能造成事故,故不建議在開發程式碼中使用此語句。
說明: TRUNCATE TABLE 在功能上與不帶 WHERE 子句的 DELETE 語句相同。

()ORM 對映

1. 【強制】在表查詢中,一律不要使用 * 作為查詢的欄位列表,需要哪些欄位必須明確寫明。
說明: 1增加查詢分析器解析成本。 2增減欄位容易與 resultMap 配置不一致。 3)無用字
段增加網路消耗,尤其是
text 型別的欄位。
2. 【強制】 POJO 類的布林屬性不能加 is,而資料庫欄位必須加 is_,要求在 resultMap 中進行
欄位與屬性之間的對映。
說明: 參見定義 POJO 類以及資料庫欄位定義規定,在<resultMap>增加對映,是必須的。
MyBatis Generator 生成的程式碼中,需要進行對應的修改。
3. 【強制】不要用 resultClass 當返回引數,即使所有類屬性名與資料庫欄位一一對應,也需
要定義
反過來,每一個表也必然有一個 POJO 類與之對應。
說明: 配置對映關係,使欄位與 DO 類解耦,方便維護。
4. 【強制】 sql.xml 配置引數使用: #{}#param# 不要使用${} 此種方式容易出現 SQL 注入。
5. 【強制】 iBATIS 自帶的 queryForList(String statementName,

相關推薦

阿里java開發規範6---MySQL資料庫

五、 MySQL 資料庫(一)建表規約1. 【強制】表達是與否概念的欄位,必須使用 is_xxx 的方式命名,資料型別是 unsigned tinyint( 1 表示是, 0 表示否)。說明: 任何欄位如果為非負數,必須是 unsigned。注意: POJO 類中的任何布林型

Java開發規範

本文摘自阿里開發規範,是阿里工程師們嚴格遵循的開發標準,同時也是培養自己寫出高質量程式碼的必然要求,不讓自己寫出來的程式碼像個剛畢業的。 1、命名的風格:1. 程式碼中的命名均不能以下劃線或美元符號開始,也不能以下劃線或美元符號結束。 反例: _name $name2.

阿里巴巴 Java 開發手冊筆記

【命名規約】 抽象類命名使用Abstract或者Base開頭 測試類名使用Test結尾 如果使用到了設計模式,在類名中體現具體的模式 OrderFactory LonginProxy 【常量定義】 long型別的初始賦值必須使用大寫的L 使用專門的類來維護常量ConfigC

java===java基礎學習6---流程控制,for,if,switch,continue,break

nbsp int exception pub ase nio 內部 註意點 多重循環 註意點: for循環的用法和python截然不同,註意格式 switch~,switch對應的case每當執行完畢都要break,由於基本不怎麽用switch,所以作為了解。 中斷流程

數據庫之mysql6—— mysql常用函數函數/自定義函數

多個 color 9.png 方法 定義 gpo 類型 好的 個數 常用函數 運算函數 我相信你都能看懂,所以以上的不再做過多解釋 然後還有個,前面漏掉的between and: 意指10是否在0到20之間,如果

windows環境下搭建Java開發環境:jdk安裝和配置

變量 win jns jdk安裝 分享 tool 直接 www. 技術 一、資源下載   官網:http://www.oracle.com/technetwork/java/javase/downloads/index.html   本人安裝的是jdk1.8,百度雲資源:鏈

Java並發6- CountDownLatch、Semaphore與AQS

退出 很好 不同的 釋放 pri bcd EDA 大型 pro 引言 上一篇文章中詳細分析了基於AQS的ReentrantLock原理,ReentrantLock通過AQS中的state變量0和1之間的轉換代表了獨占鎖。那麽可以思考一下,當state變量大於1時代表了什麽?

Java開發筆記Java工程的帝國區劃

頂部 圖片 最有 屬於 聚集地 合格 ext info 主界面 上一篇文章介紹了如何運行了第一個Java程序“Hello World”。然而這個開發環境看起來那麽陌生,一個個名字符號完全不知道它們是幹啥的呀,對於初學者來說,好比天書一般,多看幾眼感覺都要走火入魔了。因此接下

Java開發筆記Java帝國的度量衡

時間 我們 true 都是 不難 class 右鍵菜單 imp 既然 秦始皇統一中國之後,實行“書同文,車同軌”,把貨幣和各種度量衡都統一起來,從而締造了一個秩序井然的帝國。既然統一度量衡是每個帝國都要做的事情,Java帝國也不例外,對於人生地不熟的初學者來說,只有認識了J

Java開發筆記特殊數字的表達

world 表達 int 數據 decimal stat java語言 細節 進制數 之前的文章提到,Java語言不但支持大眾熟知的十進制數,也支持計算機特有的二進制數、八進制數和十六進制數。可是在給數值變量賦值的時候,等號右邊的數字明顯屬於十進制,那究竟要如何書寫其它進制

Java開發筆記賦值運算符及其演化

運行 加減 pre 存在 運算 而在 否則 四則運算 out 前面的加減乘除四則運算,計算結果通過等號輸出給指定變量,註意此時代碼把變量放到等號左邊。而在算術課本裏,加法運算的完整寫法類似於“1+1=2”這樣,運算結果應該跟在等號右邊。不過代數課本裏的方程式存在“x=y+1

「深入Java虛擬機6」:Java語法糖

拆裝箱 重載 jdk1 支持 名稱 不存在 語法糖 pub 簽名 語法糖(Syntactic Sugar),也稱糖衣語法,是由英國計算機學家Peter.J.Landin發明的一個術語,指在計算機語言中添加的某種語法,這種語法對語言的功能並沒有影響,但是更方便程序員使用。Ja

Java開發筆記數值變數的型別

如今個人電腦的配置越來越高,記憶體和硬碟的容量大小都是以G為單位,而1G=1024M=10241024K=102410241024位元組。不過在PC的早期發展階段,電腦的儲存空間卻是十分有限的,像2000年前後廣泛使用的3.5寸軟盤,其儲存容量只有區區1.44M,當時流行的SDR記憶體容

Java開發筆記一元運算子的技巧

前面講到賦值運算子的時候,提到“x = x+7”可以被“x += 7”所取代,當然Java程式設計中給某個變數自加7並不常見,常見的是給某變數自加1,就像走臺階,一般都是一級一級臺階地走,犯不著一下子跳上七級臺階。那麼對於變數自加1的情況,既可以寫成“x = x+1”,也可以寫成“x +

Java併發程式設計6:Runnable和Thread實現多執行緒的區別(含程式碼)

Java中實現多執行緒有兩種方法:繼承Thread類、實現Runnable介面,在程式開發中只要是多執行緒,肯定永遠以實現Runnable介面為主,因為實現Runnable介面相比繼承Thread類有如下優勢: 1、可以避免由於Java的單繼承特性而帶來的侷限; 2、增強程式的健壯性,程式碼能夠被多個執行

Java併發程式設計6- J.U.C元件拓展

J.U.C-FutureTask 在Java中一般通過繼承Thread類或者實現Runnable介面這兩種方式來建立執行緒,但是這兩種方式都有個缺陷,就是不能在執行完成後獲取執行的結果,因此Java 1.5之後提供了Callable和Future介面,通過它們就可以在任務執行完畢之後得到任務的執行結果。

Java開發筆記章節目錄

現將本部落格的Java學習文章整理成以下筆記目錄,方便查閱。 第一章 初識JavaJava開發筆記(一)第一個Java程式Java開發筆記(二)Java工程的帝國區劃Java開發筆記(三)Java帝國的特種官吏Java開發筆記(四)Java帝國的度量衡 第二章 數值變數Java開發筆記(五)數值變數的型別

「深入Java虛擬機器6」:Java語法糖

語法糖(Syntactic Sugar),也稱糖衣語法,是由英國計算機學家Peter.J.Landin發明的一個術語,指在計算機語言中新增的某種語法,這種語法對語言的功能並沒有影響,但是更方便程式設計師使用。Java中最常用的語法糖主要有泛型、變長引數、條件編譯、自動拆裝箱、內部類等。虛擬機器並不支援這些語法

JAVA高階基礎6---Vector和LinkedList

Vector 是 List 介面一個長度可變的陣列的實現。 可以儲存null  是同步的(是執行緒安全的) 注:更多詳細方法請自行在 API 上查詢  ArrayList和Vector的區別:是否是同步的 package or

Java程式設計思想6

第19章 列舉型別 1 enum的函式,ordinal()返回enum的int值,name()返回enum的值 enum Shrubbery {GROUND,CRAWLING,HANGING} public class TwoTuple{ public static void mai