如何定義數據表的擴展字段
因為產品升級或者產品項目適配等一些原因, 我們的關系型數據庫的數據字段需要進行擴展; 比如我們原有一張user表, 其中有id, username, password字段, 現在我們需要這個user的age, male, address屬性, 我們如何在原有的表基礎上實現擴展呢?
我們通常使用如下幾種方法來實現數據擴展: 動態添加字段、JSON格式儲存、預留字段、屬性字段行存儲
(1), 動態添加屬性字段
意思是,在需要添加一個屬性時。先在數據庫的表里添加一個字段。
比如說要給user有age的屬性,就給user表添加age字段。那么要用這個字段時,還要改相應的java程序。顯然這種方式不利於靈活擴展,而且在一張大表添加一個字段需要較長時間,這也不適合7*24的服務。
- 優點:符合數據表設計的習慣,實際使用中與原有字段基本無差別
- 缺點:每增加一個屬性就要改相應的Java程序,不利於靈活擴展
(2), JSON格式儲存
就是說把需擴展的一組字段都到到一個字段里,各個字段用JSON的方式組成一個大的字符串。
比如上邊的user表可以這樣設計:
字段 | 類型 | 備注 | 數據實例 |
---|---|---|---|
id | int(10) | ID | 1239512 |
username | varchar(20) | 用戶名 | zhangsan |
password | varchar(20) | 密碼 | qwerty |
version | int(10) | 版本(擴展字段的版本) | 3 |
extended_filed | varchar(200) | 擴展字段 | {'age': '18', 'male': 'F', 'address': 'hefei'} |
- 優點:insert/update/delete都可以比較方便的操作;不用頻繁改動表結構和過多的Java代碼
- 缺點:擴展字段不支持索引;key名大量冗余;如果要根據擴展字段進行查詢不方便,也不高效,需要遍歷所以數據;
(3), 預留字段
就是先給表定義幾個擴展字段,還是以user表為例。
給user表定義幾個預留字段,這樣任何數據類型都可以解析為字符串,把編碼后的數據存進去就行了。
字段 | 類型 | 備注 | 數據實例 |
---|---|---|---|
id | int(10) | ID | 1239512 |
username | varchar(20) | 用戶名 | zhangsan |
password | varchar(20) | 密碼 | qwerty |
extended_filed1 | varchar(50) | 預留擴展字段1 | 18 |
extended_filed2 | varchar(50) | 預留擴展字段2 | F |
extended_filed3 | varchar(50) | 預留擴展字段3 | hefei |
- 優點:可以正常的select/insert/delete/update;一些復雜的查詢也可以實現
- 缺點:太少可能起不到作用,太多也不行,影響性能;擴展字段是公用的,不能根據字段名顧名思義,得在啟用時維護對應關系,使用時查找對應關系;擴展字段的數量無法精確定義。
(4), 屬性字段行存儲
顧名思義,此方法需要新建一個屬性字段表,在這個表里維護擴展字段的字段名和字段值
如user表的擴展字段表
字段 | 類型 | 備注 | 數據實例 |
---|---|---|---|
id | int(10) | ID | 13214213 |
user_id | int(10) | user表的ID屬性 | 1239512 |
filed_name | varchar(20) | 擴展字段名 | age |
filed_value | varchar(20) | 擴展字段值 | 18 |
- 優點:字段名能夠顧名思義,字段也可以動態擴展
- 缺點:key名稱大量冗余,所以key命名盡量短,可使用編碼;select/insert/delete/update時需要操作兩張表,操作稍微復雜
(5), 擴展字段配置表和擴展字段值表
多個表的擴展字段屬性和擴展字段值,配置儲存在一張表中,值分開儲存在多張表中
擴展字段表:
擴展字段值表:
- 優點:優點:只需維護配置表即可,減少代碼維護量
- 缺點:操作比較復雜