数据字典国际化完整方案
字典类型主表 + 字典类型国际化子表 + 字典明细主表 + 字典明细国际化子表
一、定案
数据字典国际化采用"字典类型主表 + 字典类型国际化子表 + 字典明细主表 + 字典明细国际化子表"的四表主模型;运行时优先读取当前语言 i18n 值,缺失时回退主表默认值,并结合 Redis + Caffeine 按 dictType + language 做高频缓存,不再使用万能翻译表作为字典热路径主方案。
二、现有主表
1. 字典类型主表:sys_dict_type
- dict_type:业务键,继续保持稳定
- dict_name:默认语言名称
- remark:默认备注
- sort_code / system_type:排序与系统内置控制
2. 字典明细主表:sys_dict_data
- dict_type_id:关联字典类型
- dict_label:默认语言标签
- dict_value:业务值,继续保持稳定
- remark / sort_code/ system_value:说明、排序与系统值控制
三、国际化子表
1. sys_dict_type_i18n
- dict_type_id
- language_code
- dict_name
- remark
- 唯一约束:(dict_type_id, language_code)
2. sys_dict_data_i18n
- dict_data_id
- language_code
- dict_label
- remark
- 唯一约束:(dict_data_id, language_code)
3. sys_i18n_dict_publish
- dict_type
- language_code
- publish_version
- publish_time
- publish_user_id
- 唯一约束:(dict_type, language_code)
四、运行时规则
1. 字典类型回退规则
- sys_dict_type_i18n.dict_name
- sys_dict_type.dict_name
- sys_dict_type.dict_type
- id
2. 字典明细回退规则
- sys_dict_data_i18n.dict_label
- sys_dict_data.dict_label
- sys_dict_data.dict_value
- id
五、缓存设计
|--------|-----------------------------------------------------|
| 缓存项 | Key 规则 |
| 字典类型列表 | i18n:dict:type:list:{languageCode}:v{version} |
| 字典明细列表 | i18n:dict:data:{dictType}:{languageCode}:v{version} |
| 版本号 | i18n:dict:version:{dictType}:{languageCode} |
六、交付清单
- 数据字典国际化完整方案.md
- 数据字典国际化完整方案.docx
- sql/sys_dict_type_i18n.sql
- sql/sys_dict_data_i18n.sql
- sql/sys_i18n_dict_publish.sql
- sql/数据字典国际化完整SQL.sql
- sql/字典国际化查询SQL.sql
- 字典国际化缓存规范.md
sql
-- 1. 查字典类型列表
SELECT
t.id,
t.dict_type,
COALESCE(ti.dict_name, t.dict_name) AS dict_name,
COALESCE(ti.remark, t.remark) AS remark,
t.sort,
t.system_type
FROM sys_dict_type t
LEFT JOIN sys_dict_type_i18n ti
ON ti.dict_type_id = t.id
AND ti.language_code = #{languageCode}
AND ti.del_flag = 0
AND ti.enabled = 1
ORDER BY t.sort ASC, t.id ASC;
-- 2. 按 dictType 查字典项
SELECT
d.id,
t.dict_type,
d.dict_value,
COALESCE(di.dict_label, d.dict_label) AS dict_label,
COALESCE(di.remark, d.remark) AS remark,
d.sort,
d.system_value
FROM sys_dict_type t
INNER JOIN sys_dict_data d
ON d.dict_type_id = t.id
LEFT JOIN sys_dict_data_i18n di
ON di.dict_data_id = d.id
AND di.language_code = #{languageCode}
AND di.del_flag = 0
AND di.enabled = 1
WHERE t.dict_type = #{dictType}
ORDER BY d.sort ASC, d.id ASC;
-- 3. 按 dictTypeId 查字典项
SELECT
d.id,
d.dict_type_id,
d.dict_value,
COALESCE(di.dict_label, d.dict_label) AS dict_label,
COALESCE(di.remark, d.remark) AS remark,
d.sort,
d.system_value
FROM sys_dict_data d
LEFT JOIN sys_dict_data_i18n di
ON di.dict_data_id = d.id
AND di.language_code = #{languageCode}
AND di.del_flag = 0
AND di.enabled = 1
WHERE d.dict_type_id = #{dictTypeId}
ORDER BY d.sort ASC, d.id ASC;
-- 4. 查发布版本
SELECT publish_version
FROM sys_i18n_dict_publish
WHERE dict_type = #{dictType}
AND language_code = #{languageCode}
AND del_flag = 0
AND enabled = 1
LIMIT 1;
sql
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `sys_i18n_dict_publish`;
DROP TABLE IF EXISTS `sys_dict_data_i18n`;
DROP TABLE IF EXISTS `sys_dict_type_i18n`;
CREATE TABLE `sys_dict_type_i18n` (
`id` bigint NOT NULL COMMENT '主键id',
`dict_type_id` bigint NOT NULL COMMENT '字典类型ID=sys_dict_type.id',
`language_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '语言编码,如zh_CN/en_US/ja_JP',
`dict_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典名称国际化',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注国际化',
`sort_code` int NOT NULL DEFAULT '1' COMMENT '排序码',
`enabled` int NOT NULL DEFAULT '1' COMMENT '状态 0禁用 1正常',
`del_flag` int NOT NULL DEFAULT '0' COMMENT '删除标记 0正常 1删除',
`create_date` bigint DEFAULT NULL COMMENT '创建时间',
`creator` bigint NOT NULL DEFAULT '0' COMMENT '创建人id',
`update_date` bigint DEFAULT NULL COMMENT '修改时间',
`updater` bigint NOT NULL DEFAULT '0' COMMENT '修改人id',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `uk_dict_type_lang` (`dict_type_id`,`language_code`) USING BTREE,
KEY `idx_lang_type` (`language_code`,`dict_type_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='字典类型国际化表';
CREATE TABLE `sys_dict_data_i18n` (
`id` bigint NOT NULL COMMENT '主键id',
`dict_data_id` bigint NOT NULL COMMENT '字典明细ID=sys_dict_data.id',
`language_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '语言编码,如zh_CN/en_US/ja_JP',
`dict_label` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典标签国际化',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注国际化',
`sort_code` int NOT NULL DEFAULT '1' COMMENT '排序码',
`enabled` int NOT NULL DEFAULT '1' COMMENT '状态 0禁用 1正常',
`del_flag` int NOT NULL DEFAULT '0' COMMENT '删除标记 0正常 1删除',
`create_date` bigint DEFAULT NULL COMMENT '创建时间',
`creator` bigint NOT NULL DEFAULT '0' COMMENT '创建人id',
`update_date` bigint DEFAULT NULL COMMENT '修改时间',
`updater` bigint NOT NULL DEFAULT '0' COMMENT '修改人id',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `uk_dict_data_lang` (`dict_data_id`,`language_code`) USING BTREE,
KEY `idx_lang_data` (`language_code`,`dict_data_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='字典数据国际化表';
CREATE TABLE `sys_i18n_dict_publish` (
`id` bigint NOT NULL COMMENT '主键id',
`dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典类型编码=sys_dict_type.dict_type',
`language_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '语言编码',
`publish_version` bigint NOT NULL DEFAULT '1' COMMENT '发布版本号',
`publish_time` bigint DEFAULT NULL COMMENT '发布时间',
`publish_user_id` bigint NOT NULL DEFAULT '0' COMMENT '发布人',
`enabled` int NOT NULL DEFAULT '1' COMMENT '状态 0禁用 1正常',
`del_flag` int NOT NULL DEFAULT '0' COMMENT '删除标记 0正常 1删除',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `uk_dict_type_lang_publish` (`dict_type`,`language_code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='字典国际化发布表';
INSERT INTO `sys_i18n_dict_publish`
(`id`,`dict_type`,`language_code`,`publish_version`,`publish_time`,`publish_user_id`,`enabled`,`del_flag`)
VALUES
(400000000000000001,'bill_state','zh_CN',1,UNIX_TIMESTAMP()*1000,0,1,0),
(400000000000000002,'bill_state','en_US',1,UNIX_TIMESTAMP()*1000,0,1,0),
(400000000000000003,'payment_type','zh_CN',1,UNIX_TIMESTAMP()*1000,0,1,0),
(400000000000000004,'payment_type','en_US',1,UNIX_TIMESTAMP()*1000,0,1,0);
SET FOREIGN_KEY_CHECKS = 1;