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


    场景

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

    在这里插入图片描述

    实现方式有很多,我们来聊比较常用的两种,看看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='当前信息'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

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

    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='内容表'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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

    对比

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

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

    总结

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

  • 相关阅读:
    C语言之const
    SpringBoot整合redis+mysql
    Etcd教程 — 第五章 Etcd之etcdctl的使用
    Jmeter实现接口文件上传、阅览和下载
    PE文件-CPU寄存器-栈-常用汇编语言指令-push-move-sub-lea-rep-xor
    【杂叙】北京住房公积金提取
    如何成为不可替代的程序员?掌握这个方法,裁员名单永远没有你
    Day02 SpringBoot第二次笔记---开发实用篇(第三方属性的绑定、宽松绑定/松散绑定、常用计量单位绑定和数据校验)
    Git - 安装与配置
    嵌入式 C语言/C++ 常见笔试、面试题 难疑点汇总(经典100道)
  • 原文地址:https://blog.csdn.net/shida219/article/details/133517108