• 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每次有新增模块,服务端需要一起修改。但这个比较正常,大部分时候新增的功能,服务端总是需要做一些改动的

    总结

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

  • 相关阅读:
    索引使用与注意事项
    发表博客的模板
    vim快捷指令
    Learn Prompt-GPT-4:能力
    电子日历-参数
    安全专家讲述Web 渗透测试怎么做
    计组 | 交叉编址 & 流水线
    linux——环境基础开发工具使用
    安全典型配置(五)SNMP中应用ACL过滤非法网管案例
    java-php-python-ssm外卖订餐管理计算机毕业设计
  • 原文地址:https://blog.csdn.net/shida219/article/details/133517108