[Mysql教程系列]介紹一下MySQL表設計規範

點擊上方“Coder編程”,選擇“置頂公衆號”

技術文章第一時間送達!

mysql.jpg

表設計規範

1、表引擎取決於實際應用場景;日誌及報表類表建議用myisam,與交易,審覈,金額相關的表建議用innodb引擎。如無說明,建表時一律採用innodb引擎。

2、默認使用utf8mb4字符集,數據庫排序規則使用utf8mb4_general_ci,(由於數據庫定義使用了默認,數據表可以不再定義,但爲保險起見,建議都寫上)。

爲什麼字符集不選擇utf8,排序規則不使用utf8_general_ci?

採用utf8編碼的MySQL無法保存佔位是4個字節的Emoji表情。爲了使後端的項目,全面支持客戶端輸入的Emoji表情,升級編碼爲utf8mb4是最佳解決方案。對於JDBC連接串設置了characterEncoding爲utf8或者做了上述配置仍舊無法正常插入emoji數據的情況,需要在代碼中指定連接的字符集爲utf8mb4。

3、所有表、字段均應用 comment 列屬性來描述此表、字段所代表的真正含義,如枚舉值則建議將該字段中使用的內容都定義出來。

4、如無說明,表中的第一個id字段一定是主鍵且爲自動增長,禁止在非事務內作爲上下文作爲條件進行數據傳遞。禁止使用varchar類型作爲主鍵語句設計。

5、如無說明,表必須包含create_time和modify_time字段,即表必須包含記錄創建時間和修改時間的字段

6、如無說明,表必須包含is_del,用來標示數據是否被刪除,原則上數據庫數據不允許物理刪除。

7、用盡量少的存儲空間來存數一個字段的數據

  • 能用int的就不用char或者varchar

  • 能用tinyint的就不用int

  • 使用UNSIGNED存儲非負數值。

  • 不建議使用ENUM、SET類型,使用TINYINT來代替

  • 使用短數據類型,比如取值範圍爲0-80時,使用TINYINT UNSIGNED

  • 存儲精確浮點數必須使用DECIMAL替代FLOAT和DOUBLE

  • 時間字段,除特殊情況一律採用int來記錄unix_timestamp

    • 存儲年使用YEAR類型。

    • 存儲日期使用DATE類型。

    • 存儲時間(精確到秒)建議使用TIMESTAMP類型,因爲TIMESTAMP使用4字節,DATETIME使用8個字節。

  • 建議使用INT UNSIGNED存儲IPV4。

  • 儘可能不使用TEXT、BLOB類型

  • 禁止在數據庫中使用VARBINARY、BLOB存儲圖片、文件等。建議使用其他方式存儲(TFS/SFS),MySQL只保存指針信息。

  • 單條記錄大小禁止超過8k(列長度(中文)3(UTF8)+列長度(英文)1)

datetime與timestamp有什麼不同?

相同點:TIMESTAMP列的顯示格式與DATETIME列相同。顯示寬度固定在19字符,並且格式爲YYYY-MM-DD HH:MM:SS。
不同點:

  • TIMESTAMP

    • 4個字節儲存,時間範圍:1970-01-01 08:00:01 ~ 2038-01-19 11:14:07

    • 值以UTC格式保存,涉及時區轉化 ,存儲時對當前的時區進行轉換,檢索時再轉換回當前的時區。

  • datetime

    • 8個字節儲存,時間範圍:1000-01-01 00:00:00 ~ 9999-12-31 23:59:59

    • 實際格式儲存,與時區無關

如何使用TIMESTAMP的自動賦值屬性?

  • 將當前時間作爲ts的默認值:ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP。

  • 當行更新時,更新ts的值:ts TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP。

  • 可以將1和2結合起來:ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP。

如何使用INT UNSIGNED存儲ip?

使用INT UNSIGNED而不是char(15)來存儲ipv4地址,通過MySQL函數inet_ntoa和inet_aton來進行轉化。Ipv6地址目前沒有轉化函數,需要使用DECIMAL或者兩個bigINT來存儲。

8、如無備註,所有字段都設置NOT NULL,並設置默認值;

9、禁止在數據庫中存儲明文密碼

10、如無備註,所有的布爾值字段,如is_hot、is_deleted,都必須設置一個默認值,並設爲0;

11、如無備註,排序字段order_id在程序中默認使用降序排列;

12、整形定義中不添加長度,比如使用INT,而不是INT[4]

INT[M],M值代表什麼含義?

注意數值類型括號後面的數字只是表示寬度而跟存儲範圍沒有關係。很多人他們認爲INT(4)和INT(10)其取值範圍分別是 (-9999到9999)和(-9999999999到9999999999),這種理解是錯誤的。其實對整型中的 M值與 ZEROFILL 屬性結合使用時可以實現列值等寬。不管INT[M]中M值是多少,其取值範圍還是 (-2147483648到2147483647 有符號時),(0到4294967295無符號時)。

顯示寬度並不限制可以在列內保存的值的範圍,也不限制超過列的指定寬度的值的顯示。當結合可選擴展屬性ZEROFILL使用時默認補充的空格用零代替。例如:對於聲明爲INT(5) ZEROFILL的列,值4檢索爲00004。請注意如果在整數列保存超過顯示寬度的一個值,當MySQL爲複雜聯接生成臨時表時會遇到問題,因爲在這些情況下MySQL相信數據適合原列寬度,如果爲一個數值列指定ZEROFILL, MySQL自動爲該列添加UNSIGNED屬性。

13、使用VARBINARY存儲大小寫敏感的變長字符串

什麼時候用CHAR,什麼時候用VARCHAR?

CHAR和VARCHAR類型類似,但它們保存和檢索的方式不同。它們的最大長度和是否尾部空格被保留等方面也不同。CHAR和VARCHAR類型聲明的長度表示你想要保存的最大字符數。例如,CHAR(30)可以佔用30個字符。

  • CHAR列的長度固定爲創建表時聲明的長度。長度可以爲從0到255的任何值。當保存CHAR值時,在它們的右邊填充空格以達到指定的長度。當檢索到CHAR值時,尾部的空格被刪除掉。在存儲或檢索過程中不進行大小寫轉換。

  • VARCHAR列中的值爲可變長字符串。長度可以指定爲0到65,535之間的值。(VARCHAR的最大有效長度由最大行大小和使用的字符集確定。整體最大長度是65,532字節)。

同CHAR對比,VARCHAR值保存時只保存需要的字符數,另加一個字節來記錄長度(如果列聲明的長度超過255,則使用兩個字節)。VARCHAR值保存時不進行填充。當值保存和檢索時尾部的空格仍保留,符合標準SQL。

char適合存儲用戶密碼的MD5哈希值,它的長度總是一樣的。對於經常改變的值,char也好於varchar,因爲固定長度的行不容易產生碎片,對於很短的列,char的效率也高於varchar。char(1)字符串對於單字節字符集只會佔用一個字節,但是varchar(1)則會佔用2個字節,因爲1個字節用來存儲長度信息。

推薦

文末

文章收錄至
Github: https://github.com/CoderMerlin/coder-programming
Gitee: https://gitee.com/573059382/coder-programming
歡迎關注並star~

微信公衆號

                   我知道你 “在看

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