資料庫建表 SQL 索引規範

2021-10-12 21:24:16 字數 4543 閱讀 1559

【強制】(1) 儲存引擎必須使用innodb

解讀:innodb支援事物、行級鎖、併發效能更好,cpu及記憶體快取頁優化使得資源利用率更高。
【強制】(2)每張表必須設定乙個主鍵id,且這個主鍵id使用自增主鍵(在滿足需要的情況下盡量短),除非在分庫分表環境下。

解讀:由於innodb組織資料的方式決定了需要有乙個主鍵,而且若是這個主鍵id是單調遞增的可以有效提高插入的

效能,避免過多的頁**、減少表碎片提高空間的使用率。而在分庫分表環境下,則需要統一來分配各個表中的主

鍵值,從而避免整個邏輯表中主鍵重複。

【強制】(3)必須使用utf8mb4字符集

解讀:在mysql中的utf-8並非「真正的utf-8」,而utf8mb4」才是真正的「utf-8」。mysql中utf-8只有三個位元組
【強制】(4) 資料庫表、表字段必須加入中文注釋

解讀:大家都別懶
【強制】(5) 庫名、表名、欄位名均小寫,下劃線風格,不超過32個字元,必須見名知意,禁止拼音英文混用。

解讀:約定
解讀:單表列數太多使得mysql伺服器處理innodb返回資料之間的對映成本太高
【強制】(7)禁止使用外來鍵,如果有外來鍵完整性約束,需要應用程式控制

成死鎖。

【強制】(8)必須把字段定義為not null並且提供預設值

解讀:

a、null的列使索引/索引統計/值比較都更加複雜,對mysql來說更難優化

b、null這種型別msql內部需要進行特殊處理,增加資料庫處理記錄的複雜性;同等條件下,表中有較多空字段的

時候,資料庫的處理效能會降低很多

c、null值需要更多的儲存空,無論是表還是索引中每行中的null的列都需要額外的空間來標識

【強制】(9)禁用保留字,如desc、range、march等,請參考mysql官方保留字。

【強制】(10)如果儲存的字串長度幾乎相等,使用char定長字串型別。

解讀:能夠減少空間碎片,節省儲存空間。
【建議】(11)在一些場景下,考慮使用timestamp代替datetime。

解讀:a、這兩種型別的都能表達"yyyy-mm-dd hh:mm:ss"格式的時間,timestamp只需要占用4個位元組的長度,

可以儲存的範圍為(1970-2038)年,在各個時區,所展示的時間是不一樣的;

b、而datetime型別占用8個位元組,對時區不敏感,可以儲存的範圍為(1001-9999)年。

*** 【建議】(12)當心自動生成的schema,建議所有的schema手動編寫。**

解讀:對於一些資料庫客戶端不要太過信任。
【建議】 (1) 為了充分利用快取,不允許使用自定義函式、儲存函式、使用者變數。

解讀:如果查詢中包含任何使用者自定義函式、儲存函式、使用者變數、臨時表、mysql庫中的系統表,其查詢結果都不

會被快取。比如函式now()或者current_date()會因為不同的查詢時間,返回不同的查詢結果。

*【強制】(2)在查詢中指定所需的列,而不是直接使用「 」返回所有的列

解讀:a)讀取不需要的列會增加cpu、io、net消耗 

b)不能有效的利用覆蓋索引

【強制】(3)不允許使用屬性隱式轉換

解讀:假設我們在手機號列上新增了索引,然後執行下面的sql會發生什麼?

explain select user_name from parent where phone=13812345678; 很明顯就是索引不生效會全表掃瞄。

【建議】(4)在where條件的屬性上使用函式或者表示式

解讀:mysql無法自動解析這種表示式,無法使用到索引。
【強制】(5)禁止使用外來鍵與級聯,一切外來鍵概念必須在應用層解決。

解讀:外來鍵與級聯更新適用於單機低併發,不適合分布式、高併發集群;級聯更新是強阻塞,存在資料庫更新風暴的

風險;外來鍵影響資料庫的插入速度。

【建議】(6)應盡量避免在where子句中使用or作為連線條件

解讀:根據情況可以選擇使用union all來代替or
【強制】(7)不允許使用%開頭的模糊查詢

解讀:根據索引的最左字首原理,%開頭的模糊查詢無法使用索引,可以使用es來做檢索。索引規約
【建議】(8)避免在更新比較頻繁、區分度不高的列上單獨建立索引

解讀:區分度不高的列單獨建立索引的優化效果很小,但是較為頻繁的更新則會讓索引的維護成本更高
【強制】(9) join的表不允許超過五個。需要join的字段,資料型別必須絕對一致; 多表關聯查詢時,保證被關聯的字段需要有索引

解讀:太多表的join會讓mysql的優化器更難權衡出乙個「最佳」的執行計畫(可能性為表數量的階乘),同時要注意

關聯欄位的型別、長度、字元編碼等等是否一致。

【強制】(10)在乙個聯合索引中,若第一列索引區分度等於1,那麼則不需要建立聯合索引。

解讀:索引通過第一列就能夠完全定位的資料,所以聯合索引的後邊部分是不需要的。
【強制】(11)建立聯合索引時,必須將區分度更高的字段放在左邊

編寫sql的where條件中有多個條件時,需要先看看當前表是否有現成的聯合索引直接使用,注意各個條件的順序盡

量和索引的順序一致。

【建議】(12)利用覆蓋索引來進行查詢操作,避免回表

解讀:覆蓋查詢即是查詢只需要通過索引即可拿到所需data,而不再需要再次回表查詢,所以效率相對很高。我們在

使用explain的結果,extra列會出現:"using index"。這裡也要強調一下不要使用「select * 」,否則幾乎不

可能使用到覆蓋索引。

【建議】(13)在較長varchar欄位,例如varchar(100)上建立索引時,應指定索引長度,沒必要對全欄位建立索引,根據實際文字區分度決定索引長度即可。

解讀:索引的長度與區分度是一對矛盾體,一般對字串型別資料,若長度為20的索引,區分度會高達90%以上,則

可以考慮建立長度例為20的索引,而非全欄位索引。例如可以使用select count(distinct left(lesson_cod

e, 20)) / count(*) from lesson;來確定lesson_code欄位字元長度為20時文字區分度。

【建議】(14)如果有order by的場景,請注意利用索引的有序性。order by最後的字段是聯合索引的一部分,並且放在索引組合順序的最後,避免出現file_sort的情況,影響查詢效能

解讀:1、假設有查詢條件為where a=? and b=? order by c; 存在索引:a_b_c,則此時可以利用索引排序。

2、反例:在查詢條件中包含了範圍查詢,那麼索引有序性無法利用,如:where a>10 order by b; 索引

a_b無法排序。

【建議】(15)在where中索引的列不能某個表示式的一部分,也不能是函式的引數。

解讀:即是某列上已經新增了索引,但是若此列成為表示式的一部分、或者是函式的引數,mysql無法將此列單獨解

析出來,索引也不會生效。

【建議】 (16)我們在where條件中使用範圍查詢時,索引最多用於乙個範圍條件,超過乙個則後邊的不走索引。

解讀:mysql能夠使用多個範圍條件裡邊的最左邊的第乙個範圍查詢,但是後邊的範圍查詢則無法使用。
【建議】 (17)在多個表進行外連線時,表之間的關聯字段型別必須完全一致

解讀:當兩個表進行join時,字段型別若沒有完全一致,則加索引也不會生效,這裡的完全一致包括但不限於欄位類

型、字段長度、字符集、collection等等

資料庫建表規範

1 innodb禁止使用外來鍵約束,可以通過程式層面保證。2 儲存精確浮點數必須使用decimal替代float和double。3 整型定義中無需定義顯示寬度,比如 使用int,而不是int 4 4 不建議使用enum型別,可使用tinyint來代替。5 盡可能不使用text blob型別,如果必須...

資料庫設計 建表規範

文章整理自網路 原文 1.2.3.4.基本建表規範 1.自增主鍵一般都需要設定 id int unsigned not nullauto increment 2.不定長字串長度使用varchar型別,需要考慮實際業務最長長度的基礎上擴容20 到40 為宜,且長度取2的指數長為宜 64,128,256...

資料庫建表設計規範

mysql 的字符集支援涉及兩個方面 字符集 character set 和排序方式 collection 對字符集的支援可以細化到四個層次 伺服器 server 資料庫 database 資料表 table 連線 connection 連線mysql 可通過如下命令檢視字符集的詳情 對資料庫的命名...