web工程設計<數據模型>
Schema與數據類型優化
良好的邏輯設計和物理設計是高性能的基石,應該根據系統將要執行的查詢語句來設計schema,這往往需要權衡各種因素。
一:選擇優化的數據類型
①:更小的通常更好
整數類型:MySQL支持SQL標準整數類型 INTEGER
(或INT
)和 SMALLINT
。作為一個可擴展標準,MySQL也支持整數類型 TINYINT
,MEDIUMINT
和 BIGINT
。下表顯示了每種整數類型所需的存儲和範圍。
表11.1 MySQL支持的整數類型所需的存儲和範圍
類型 | 存儲(字節) | 最小值簽名 | 最小值無符號 | 最大值簽名 | 最大值無符號 |
---|---|---|---|---|---|
TINYINT |
1 | -128 |
0 |
127 |
255 |
SMALLINT |
2 | -32768 |
0 |
32767 |
65535 |
MEDIUMINT |
3 | -8388608 |
0 |
8388607 |
16777215 |
INT |
4 | -2147483648 |
0 |
2147483647 |
4294967295 |
BIGINT |
8 | -263 |
0 |
263-1 |
264-1 |
定點類型(精確值) - DECIMAL,NUMERIC
該DECIMAL
和NUMERIC
類型的存儲精確的數值數據。在保持精確精度很重要時使用這些類型,例如使用貨幣數據。在MySQL中,NUMERIC
DECIMAL
,所以下面的註釋DECIMAL
同樣適用於 NUMERIC
。
salary DECIMAL(5,2)
浮點類型(近似值) - FLOAT,DOUBLE
FLOAT
和DOUBLE
類型代表近似數字數據值。MySQL對於單精度值使用四個字節,對於雙精度值使用八個字節。
比特值類型 - BIT
該BIT
數據類型被用於存儲比特值。一種 能夠存儲位值的類型。 範圍從1到64。
超出範圍和溢出處理
當MySQL將值存儲在超出列數據類型允許範圍的數值列中時,結果取決於當時生效的SQL模式:
-
-
- 如果啟用了嚴格的SQL模式,則MySQL會根據SQL標準拒絕帶有錯誤的超出範圍的值,並且插入失敗。
- 如果未啟用限制模式,MySQL會將值剪輯到列數據類型範圍的相應端點,並存儲結果值。當超出範圍的值分配給整數列時,MySQL會存儲表示列數據類型範圍的相應端點的值。
-
-
-
- 當為浮點或定點列分配的值超出指定(或默認)精度和比例所隱含的範圍時,MySQL會存儲表示該範圍的相應端點的值。
-
時間類型:DATE,DATETIME和TIMESTAMP類型
DATE
類型用於具有日期部分但沒有時間部分的值。MySQL DATE
以‘YYYY-MM-DD‘
格式檢索和顯示 值 。支持的範圍是 ‘1000-01-01‘
到 ‘9999-12-31‘
。
DATETIME
類型用於包含日期和時間部分的值。MySQL DATETIME
以‘YYYY-MM-DD HH:MM:SS‘
格式檢索和顯示 值。支持的範圍是 ‘1000-01-01 00:00:00‘
到‘9999-12-31 23:59:59‘
。
TIMESTAMP
數據類型被用於同時包含日期和時間部分的值。 TIMESTAMP
具有‘1970-01-01 00:00:01‘
UTC到‘2038-01-19 03:14:07‘
UTC 的範圍。
選擇:TIMESTAMP只使用了
DATETIME的一半的存儲空間,並且會根據時區變化,具有特殊的自動更新能力,但是
TIMESTAMP允許的時間範圍小得多,這是它的一個障礙。
字符類型:
CHAR和VARCHAR類型 相似,但它們被存儲和檢索的方式不同。它們的最大長度和尾隨空間是否保留也不同。
下表說明之間的差別 CHAR
和VARCHAR
通過顯示存儲各種字符串值到的結果 CHAR(4)
和VARCHAR(4)
列(假設該列使用單字節字符集,例如latin1
)。
更多詳情:https://dev.mysql.com/doc/refman/8.0/en/binary-varbinary.html
值 | CHAR(4) | 需要存儲 | VARCHAR(4) | 需要存儲 |
---|---|---|---|---|
‘‘ |
‘ ‘ |
4字節 | ‘‘ |
1個字節 |
‘ab‘ |
‘ab ‘ |
4字節 | ‘ab‘ |
3個字節 |
‘abcd‘ |
‘abcd‘ |
4字節 | ‘abcd‘ |
5個字節 |
‘abcdefgh‘ |
‘abcd‘ |
4字節 | ‘abcd‘ |
5個字節 |
②:簡單就好
簡單的數據類型操作需要更少的cpu周期:
整型比字符操作更低(因為字符集的校對規則決定了比整型更復雜)
③:盡量避免null
通常很多應用程序需求不要使用到null的值,但是還是很多字段屬性默認為null(最好為not null):
null的列使索引,索引統計和值得比較變得復雜起來,可能null的列會使用更多的存儲空間;當可為null的列上創建索引時,每個索引需要一個額外的字節。
調優:通常避免將索引建在為null的列上,誤建了,可將null更改成not null 提升性能
二:schema中的設計缺陷
討論mysql的schema的設計問題,可以避免發生一些問題錯誤,並且選擇mysql中實現最好的替代方案。
①:太多列
存儲引擎在存儲數據時,需要在存儲層api和服務層之間通過緩沖格式拷貝數據
web工程設計<數據模型>