Mysql以key-val存储、正常存储的区别

场景

你作为一个服务端工程师,假设产品要求设计这么一个页面,页面上包含很多模块,每个模块都可以单独进行变更,有些模块是富文本。

Mysql以key-val存储、正常存储的区别_第1张图片

实现方式有很多,我们来聊比较常用的两种,看看mysql的表如何设计。

第一种使用key-val的方案,这就需要两张表。

CREATE TABLE `playground` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '名称',
  `operator_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '操作人id',
  `status` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '状态,1使用 2删除',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_operator_id` (`operator_id`),
  KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB COLLATE=utf8mb4_general_ci COMMENT='playground项目信息'


CREATE TABLE `current_info` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `playground_id` bigint unsigned NOT NULL COMMENT 'playground_id',
  `item_type` int NOT NULL DEFAULT '0' COMMENT '每个模块的id',
  `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '模块内容',
  `operator_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '操作人id',
  `status` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '状态,1使用 2删除',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_playground_id` (`playground_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='当前信息'

第二种方式则是放在一张表记录

CREATE TABLE `current_info` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '名称',
  `description` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '描述',
  `status` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '状态,0无效,1有效',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `creator_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '创建者ID',
  `a` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'a模块内容',
  `b` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'b模块内容',
  PRIMARY KEY (`id`),
  KEY `idx_creator_id` (`creator_id`),
  KEY `idx_create_time` (`create_time`),
  KEY `idx_update_time` (`update_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='内容表'

对于这两种方案,你会如何选择?

对比

我个人建议选择正常存储的方案,因为适应面更加广泛

Key-val 正常存储
优点 增加新模块,服务端无需感知,前端自行增加即可 实现复杂度低很多
缺点 1. 即使是普通的列表,实现起来也比较复杂,必须有一张主表 2.列表排序、筛选不好实现,如按照修改时间排序、根据名称筛选等 3.数量多,页面数据会有多条 4.字段浪费严重,每个字段必须一样,大部分情况是是text 每次有新增模块,服务端需要一起修改。但这个比较正常,大部分时候新增的功能,服务端总是需要做一些改动的

总结

对于技术方案的选择,十分重要,尤其是作为第一版的设计者。怎么知道哪个方案更加合适呢?我的想法是找到当前的各个场景和预判将来的各个场景,思考一下如果用某套方案实现这些场景,成本如何。

你可能感兴趣的:(架构,后端)