数据字典表设计

本文介绍了数据字典在开发中的应用,特别是在行业、省市区等多级下拉选择业务中的使用。通过创建一个包含id、name、value、type、grade、sort和pid等字段的enum表来实现。查询方式包括下拉选查询和树状结构查询,用于获取不同级别的分类数据。此外,还详细阐述了字段的含义和查询示例。

数据字典

1.需求

在开发中数据字典常被用于行业、省市区等下拉选业务中。

以下图为例,我们需要设计一个公共的数据字典表以适用于行业、省市区等多种类型的多级连带的下拉选业务

image-20220310104850645

2.表机构设计

idvarchar32主键
namevarchar32枚举名称
valuevarchar32枚举值
typevarchar32枚举类型
gradeint1等级(1:一级,2:二级,3:三级依次类推)
sortint11排序
pidvarchar32枚举上级id
delint10正常1删除

2.1 建表语句

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for enum
-- ----------------------------
DROP TABLE IF EXISTS `enum`;
CREATE TABLE `enum`  (
  `id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '主键',
  `name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '枚举名称',
  `value` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '枚举值',
  `type` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '枚举类型',
  `grade` int(1) NULL DEFAULT 1 COMMENT '等级',
  `sort` int(11) NULL DEFAULT NULL COMMENT '排序',
  `pid` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '枚举上级id',
  `del` int(1) NULL DEFAULT 0 COMMENT '0正常1删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

3.字段说明

**id:**这里其实id字段是可以选项,定义规则如:TELECOM_TRADE_TYPE对应1-xxx,MOBILE_TRADE_TYPE对应2-xxx

**name:**内容

**value和pid:**以下图为例,前面是定义了一级栏目,后面定义的是二级栏目;三级栏目以此类推,只需要将二级栏目的value值设置为对应三级栏目的pid即可。

type: 首先时便于查询,其次是可以根据不同的type定义相同value和pid

sort: 用于排序

**grade:**表示级别,如一级栏目grade=1,二级栏目grade=2,三级栏目grade=3 以此类推

**del:**逻辑删除状态 0-正常,1-删除

image-20220310105344274

image-20220310110044136

4.查询

1.下拉选查询方式

获取一级栏目

SELECT
	`value` AS id,
	`name` AS NAME 
FROM
	`enum`  where  `type` = 'TELECOM_TRADE_TYPE'
	AND grade = 1 
	AND del = 0 
order by sort

image-20220310124514146

查询子级栏目

在查询到一级栏目之后,前端可以获取到所有一级栏目的id,子级栏目的查询时可以作为pid进行查询,以此类推

 SELECT
        `value` as id,
        `name` as name
        FROM
        `enum`
           where `type` = 'TELECOM_TRADE_TYPE'
            AND pid = #{pid}
            and del = 0
        order by sort

2.树状结构查询

SELECT
	a.VALUE
	AS id,
	a.NAME AS NAME,
	b.
VALUE
	AS id1,
	b.NAME AS name1 
FROM
	`enum` a
	LEFT JOIN `enum` b ON b.pid = a.`value` 
	AND b.`del` = 0 
WHERE
	a.type = #{type} AND  a.`del` = 0 and a.`grade`=1 ORDER BY a.`sort`,b.`sort`

image-20220310124447614

<think>我们正在讨论后端数据字典表设计方法,目标是寻找最佳实践。根据引用内容,我们可以总结出几个关键点: 1. 引用[1]提到数据字典在系统中应用后,能让数据更加严谨。说明数据字典的重要性在于维护数据的规范性和一致性。 2. 引用[2]讨论了数据字典表设计,建议将多个字典表合并,避免每个业务模块都设计单独的字典表。这样可以减少表的数量,便于管理。 3. 引用[3]指出将数据字典项都定义在一个Java文件中虽然简单,但维护困难,特别是当字典项很多时。这暗示了我们需要一个更灵活、易于维护的方案。 4. 引用[4]提出了枚举字典的两种方案:前端写死字典表或由后端提供字典接口。这涉及到前后端交互中字典数据的使用问题。 结合这些引用,我们可以设计一个后端数据字典表的最佳实践方案: ### 一、数据字典表设计 采用“大字典表”设计,将系统中所有类型的字典项存储在一张表中,通过类型字段区分不同字典。表结构如下: ```sql CREATE TABLE sys_dict ( id BIGINT PRIMARY KEY AUTO COMMENT '主键', dict_type VARCHAR(50) NOT NULL COMMENT '字典类型(如:gender, user_status)', dict_code VARCHAR(50) NOT NULL COMMENT '字典编码(如:1, 2, "MALE")', dict_value VARCHAR(100) NOT NULL COMMENT '字典值(如:男, 女, 正常)', sort INT DEFAULT 0 COMMENT '排序', remark VARCHAR(200) COMMENT '备注', UNIQUE KEY (dict_type, dict_code) ) COMMENT='系统字典表'; ``` **字段说明**: - `dict_type`:字典类型,用于区分不同业务场景(如性别、状态等) - `dict_code`:字典编码,后端存储和传输的值(通常为数字或短字符串) - `dict_value`:字典值,展示给用户看的值 **示例数据**: | dict_type | dict_code | dict_value | sort | |-----------|-----------|------------|------| | gender | 1 | 男 | 1 | | gender | 2 | 女 | 2 | | user_status| 0 | 禁用 | 1 | | user_status| 1 | 启用 | 2 | ### 二、后端服务设计 1. **字典缓存**:系统启动时加载全量字典到缓存(如Redis),避免频繁查询数据库 2. **接口设计**: - 获取所有字典类型:`GET /dict/types` - 按类型获取字典项:`GET /dict/items?type=gender` - 批量获取字典项:`POST /dict/batch-items`(传递多个类型) ### 三、前后端交互方案 采用引用[4]的**方案二**:后端只传递字典编码,前端通过字典接口获取完整字典数据 ```json // 用户接口返回 { "id": 1, "name": "张三", "gender": 1 // 只返回字典编码 } // 前端单独调用字典接口缓存数据 // 初始化时调用 GET /dict/items?type=gender [ {"code": "1", "value": "男"}, {"code": "2", "value": "女"} ] ``` ### 四、性能优化 1. **缓存策略**:使用Redis Hash存储字典,Key为`sys_dict:${dict_type}`,结构: ``` HSET sys_dict:gender 1 "男" 2 "女" ``` 2. **更新机制**:字典变更时同步更新缓存(通过消息队列或数据库触发器) ### 五、枚举映射(Java示例) 创建枚举类与字典类型关联: ```java public enum GenderEnum { MALE(1, "男"), FEMALE(2, "女"); private final int code; private final String value; // 构造方法、getter public static String getValueByCode(int code) { // 从缓存获取,避免硬编码 return DictCache.get("gender", code); } } ``` ### 六、最佳实践总结 | 设计要点 | 实现方案 | 优势说明 | |------------------|-------------------------------------|----------------------------------| | **表结构** | 单表存储所有字典类型 | 减少表数量,统一管理[^2] | | **前后端交互** | 后端只返回code,前端维护字典映射 | 降低网络传输量[^4] | | **缓存机制** | Redis Hash按类型存储 | 快速查询,减轻数据库压力 | | **枚举支持** | 动态关联字典数据 | 避免硬编码,便于维护[^3] | | **变更通知** | 数据库触发器+消息队列 | 保证缓存一致性 | ### 注意事项 1. 字典类型命名采用`snake_case`风格(如`user_status`) 2. 禁止删除字典项(只做禁用标记),避免历史数据关联失效 3. 国际化场景增加`language`字段支持多语言 --- §§相关问题§§ 1. 如何设计支持多语言的数据字典表? 2. 数据字典变更后如何实时通知前端更新? 3. 在微服务架构中如何共享数据字典? 4. 数据字典与枚举类如何实现自动映射?</think>### 后端数据字典表设计最佳实践 根据引用内容和行业实践,后端数据字典表设计核心在于**平衡灵活性与规范性**,以下是经过验证的最佳实践方案: --- #### 一、基础表结构设计(推荐方案) ```sql CREATE TABLE sys_dict ( id BIGINT PRIMARY KEY AUTO COMMENT '主键', dict_type VARCHAR(50) NOT NULL COMMENT '字典类型(如:gender, order_status)', dict_code VARCHAR(50) NOT NULL COMMENT '字典编码(如:1, "A")', dict_value VARCHAR(100) NOT NULL COMMENT '字典值(如:男, 已支付)', sort INT DEFAULT 0 COMMENT '排序', is_enable TINYINT DEFAULT 1 COMMENT '是否启用', remark VARCHAR(200) COMMENT '备注', UNIQUE KEY (dict_type, dict_code) ) COMMENT='系统字典表'; ``` **设计要点**: 1. **单表存储所有字典** - 合并类型相近的字典(如用户状态、订单状态)避免多表管理[^2] - 通过`dict_type`字段区分业务场景 2. **编码规范** ```java // 枚举类示例(Java) public enum DictType { GENDER("gender"), USER_STATUS("user_status"), ORDER_STATUS("order_status"); } ``` 3. **索引优化** - 唯一索引:`(dict_type, dict_code)` 防止重复编码 - 覆盖索引:`dict_type` 提高查询效率 --- #### 二、前后端交互方案 **方案对比**: | 方案 | 实现方式 | 适用场景 | 缺点 | |---------------------|----------------------------------|-------------------------|--------------------------| | **前端维护字典** | 前端写死字典映射关系 | 小型项目/静态字典 | 修改需发版[^4] | | **后端接口返回** | 后端提供`/api/dict/{type}`接口 | 中大型项目/动态字典 | 增加网络请求 | | **混合方案** | 基础字典前端维护+业务字典接口获取 | 推荐方案[^4] | 实现略复杂 | **接口示例**: ```json // GET /api/dict/gender [ {"code": "1", "value": "男"}, {"code": "2", "value": "女"}, {"code": "0", "value": "未知"} ] ``` --- #### 三、性能优化策略 1. **缓存机制** ```java // Spring Boot伪代码 @Cacheable(value = "dictCache", key = "#dictType") public List<DictItem> getDictItems(String dictType) { return dictMapper.selectByType(dictType); } ``` - 使用Redis缓存字典数据,降低DB压力 - 缓存更新:通过`@CacheEvict`监听字典变更 2. **懒加载优化** - 首次访问时加载全量字典到内存 - 定时任务刷新变更字典 --- #### 四、枚举集成方案 ```java // 枚举与字典集成(Java示例) public enum GenderEnum { MALE("1", "男"), FEMALE("2", "女"); private final String code; private final String value; // 从字典表动态初始化 static { DictService.loadEnum(GenderEnum.class); } } ``` **优势**: - 编译时检查编码正确性 - 业务代码直接使用枚举值 - 保持与字典表同步更新[^3] --- #### 五、高级特性实现 1. **多语言支持** ```sql ALTER TABLE sys_dict ADD language VARCHAR(10) DEFAULT 'zh-CN'; ``` - 通过`language`字段实现国际化 2. **层级字典设计** ```sql ALTER TABLE sys_dict ADD parent_code VARCHAR(50) DEFAULT '0'; ``` - 实现树形结构(如地区字典) 3. **变更审计** ```sql ALTER TABLE sys_dict ADD create_time DATETIME DEFAULT CURRENT_TIMESTAMP, ADD update_time DATETIME ON UPDATE CURRENT_TIMESTAMP; ``` --- #### 六、最佳实践总结 | 设计原则 | 实现方案 | 收益说明 | |-------------------|----------------------------------|--------------------------| | **统一存储** | 单表存储所有字典类型 | 降低维护成本[^2] | | **编码规范** | 使用枚举约束业务代码 | 避免魔法值[^3] | | **缓存优化** | Redis+本地内存二级缓存 | 提升访问性能 | | **前后端解耦** | 提供标准化字典接口 | 独立更新字典[^4] | | **可扩展性** | 预留多语言/层级字段 | 适应业务发展 | > **关键提示**:禁止在业务表中直接存储字典文本值(如`varchar '男'`),应始终存储字典编码(如`tinyint 1`),通过关联字典表获取显示值。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值