如何使用enum資料型別?
在做資料庫設計時,我們經常需要給很多表增加一個‘型別’ 欄位,比如人的性別有‘男’, ‘女’,學校的型別有‘幼兒園’,‘小學’,‘中學’,‘大學’,汽車的型別有‘轎車’,‘suv’,‘mpv’等, 這種欄位的本質特點是它們包含 “有限個離散值”。
對於這種欄位,使用enum資料型別是最合適的,mysql和PostgreSQL都有此資料型別。 enum型別有這麼一些特點:
1、 在表中enum欄位儲存的實際是其順序值(整數),而不是字串。
2、 按照enum值做查詢和比較的時候,按照順序值來查詢和比較,而不是按照enum項的字串。不過mysql在這個方面有個問題(見下文截圖):與其某個enum項相同的字串做範圍比較(>, <, >=, <=)時候,並沒有按照順序值比較,而是按照字面值比較了。但是mysql在按照enum列做排序的時候,卻也能夠正確滴按照enum項的順序值來排序。
3、 postgresql的enum型別需要預先定義好,然後在create table的時候使用該型別。這樣做的好處是多個表可以使用同一個enum型別,不必多次定義而導致不一致等問題。
4、 可以對enum列定義索引,索引key排序也是按照enum順序值排序,並且索引key也是enum順序值(整數)。
下面的截圖是使用崑崙分散式資料庫做的示例 。裡面mysql的示例是使用崑崙分散式資料庫的儲存節點(mysql8.0.15)做的。
建立使用enum資料型別的表,然後插入資料。
對enum型別的列做範圍查詢和等值查詢,順序值決定enum項的大小關係。
按照enum型別的列排序時候,會按照其順序值而不是字面字串 做排序。查詢後設資料表可以看到enum型別的後設資料。
mysql的enum用法:可以做等值查詢,但是範圍查詢沒有按照順序值而是按照enum項的 字面字串 來比較的,這樣做其實是錯誤的。
mysql中enum列的定義,按照 enum項 出現的順序給每個enum項賦予 順序值,從0開始。
按照enum列排序時,是按照enum項 的 順序值來排序的。從後設資料字典可以看到‘職級’這個enum型別的enum項的順序值。
插入更多行後,再次排序,仍然是按照enum列的順序值而不是字面字串 來排序的。
mysql對enum列也是按照順序值排序,但是與enum字串做大小比較時候無法聰明滴按照順序值來比較。
在舉例說明enum的用法之後,我列舉一下不使用enum的資料庫設計當中不好的設計方案。這些方案應該被摒棄,切不可模仿。
1、 有人直接使用字串型別,比如varchar(N) 型別的列,來儲存這樣的欄位值,這樣的問題是,有可能上層應用的錯誤會輸入意外的欄位值,比如上例中學校型別欄位,如果應用層資料處理不充分,導致插入一行Rx.type = ‘大 學’,那麼這樣的行Rx也完全可以插入到表中。於是當你查詢 型別=‘大學’ 的行時候,就找不到Rx了。還有一個問題是空間利用率問題。在mysql和postgresql中,enum欄位實際儲存的是enum值的數值,通常會比儲存字串節省空間,而且在查詢和比較時,數值比較也比字串比較更快。
2、 另有人會在db的表中使用數字來代表型別,然後在應用層完成數字與型別字串的轉換。比如上例學校型別中,用1代表‘幼兒園’,2代表‘小學’等,然後在應用層完整這種數字與字串之間的轉換,向終端使用者展示字串,向db的對應欄位中存入數字。這樣做的問題是,增加了應用層開發的工作量和維護開銷。設想後期需要增加更多型別值,還要修改應用層程式碼。而且,沒有應用層程式碼,還完全無法理解欄位值的意義(當然,可以增加註釋說明),影響資料的可讀性。
從這裡可以看出enum型別的幾個優點:
1、 資料校驗,拒絕非法值。
2、 高效儲存和計算。
3、 資料可讀性強,不需要依賴應用程式碼來解釋。
4、 不需要應用程式做任何數值解釋和轉換,降低應用軟體開發和維護的成本。
所以,強烈建議資料庫設計和應用系統設計的時候,適當的時候使用enum型別。
推薦閱讀
-END-
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70011764/viewspace-2853161/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ENUM列舉型別型別
- 資料結構複習-01enum列舉型別資料結構型別
- Java - Enum 列舉型別Java型別
- Java列舉型別enum的詳解及使用Java型別
- mysql之ENUM列舉型別MySql型別
- 支援 enum 型別的欄位允許為空插入資料庫型別資料庫
- Python的資料型別都有哪些?如何使用?Python資料型別
- PHP 用 Enum 限定引數型別PHP型別
- [原創] sql mode與 enum 型別SQL型別
- C++typedef宣告,enum列舉型別C++型別
- 基本資料型別與API引用型別的使用資料型別API
- js資料型別之基本資料型別和引用資料型別JS資料型別
- 資料型別: 資料型別有哪些?資料型別
- swift基本資料型別使用-字典使用Swift資料型別
- 強資料型別和弱資料型別資料型別
- 區別值型別資料和引用型別資料型別
- 如何判斷JavaScript的資料型別?JavaScript資料型別
- JavaScript的資料型別如何判斷JavaScript資料型別
- 資料型別,型別轉換資料型別
- 資料型別資料型別
- 【BBED】使用bbed修改字元型別資料字元型別
- 3. php資料型別、資料型別轉換PHP資料型別
- JAVA中基本資料型別和引用資料型別Java資料型別
- 基本資料型別與字串型別資料型別字串
- PLSQL Language Reference-PL/SQL資料型別-SQL資料型別-使用者定義的PL/SQL子型別SQL資料型別
- SQL稽核 | 如何快速使用 SQLE 稽核各種型別的資料庫SQL型別資料庫
- Java中的基本資料型別與引用資料型別Java資料型別
- MySQL基礎之----資料型別篇(常用資料型別)MySql資料型別
- Enum列舉型別實戰總結,保證有用!型別
- C# Enum列舉型別操作擴充套件類C#型別套件
- SQL Server日期資料型別DATE的使用SQLServer資料型別
- python入門使用(四):資料型別Python資料型別
- golang資料型別基本介紹與使用Golang資料型別
- Mysql資料庫學習(二):資料型別(數值型別 日期和時間型別 字串型別)MySql資料庫資料型別字串
- php資料型別PHP資料型別
- Symbol資料型別Symbol資料型別
- JavaScript - 資料型別JavaScript資料型別
- 資料型別2資料型別