本文最后更新于:June 30, 2023 pm

本文作者:[wangwenhai] # 概要:本文主要介绍如何存储动态结构的数据

动态表结构设计

1.场景概述

​ 我们在平时的开发过程中,难免会遇到这种情况:某个业务需求的数据是没有固定结构的,也就是动态结构。遇到这种问题以后,大部分人当然采取的是传统的表关联的形式来做,但是这样做起来很麻烦,中间表多,会引起一些额外的技术问题。

​ 个人在项目过程中就遇到了类似问题:某个商店的卖的一些商品需要做一个动态管理,但是谁也不知道新来的商品都是什么,有可能是一个指甲刀,也有可能是一桶泡面,我们无法预测未来入仓的商品的具体数据结构和属性。例如指甲刀有力度属性,但是泡面又有蛋白质含量属性,我们不能用一个通用的数据结构去描述。

​ 在上面的案例中,我个人的解决方案是:采取文档数据库MongoDB来作为存储工具,当然实际情况下,大家可以采取自己擅长的NoSql数据库来实现。下面就来分析设计一下解决方案。

2.简单分析设计

​ 首先我们最大的问题是:无法预测表结构,也就是动态数据结构。传统的关系数据库此时就无法友好的解决这类问题,此时需要有No Schema(无结构)的数据库。我们知道MongoDB具有动态结构的特性,所以本次设计我们采取MongoDB。

​ 大致思路就是:关系数据库来描述固定数据,比如我们定义一个Mysql表结构,作为基础固定数据来存储,然后定义一个结构去描述这个数据的动态结构。这句话听起来比较绕,我详细介绍一下。

​ 如果商品都有名称(name)属性,则我们的MySql基础字段首先包含公共部分。然后新来的一个商品是指甲刀,我们上库的时候才知道指甲刀有力度这个属性,力度一般是1-10的值。接下来需要定义一个描述规则,在这里我用JSON去描述:

[
  {
"field":"force",
"type":"integer",
"default":0,
"label":"力度"
  }
]

​ 在上面的描述规则中,我们定义了一个属性,字段叫force,类型是一个integer,默认值为0,UI显示为:力度。因为字段数量不确定,所以我们最外层是一个数组。这个JSON数组对应描述了一系列的属性,也就是对应了MongoDB的一个表结构。

​ 其实这样看来,就比较明确了我们的做法:用关系数据结构来固定基本字段,然后用一个结构来描述,用非关系数据库来存储具体的数据。

​ 接下来我们做具体表结构设计。

3.表结构设计

  1. 商品基本信息表:goods

    字段名 类型 备注
    id INT(11) ID
    name VARCHAR(50) 名称
    properties JSON 描述

    需要注意一下:Mysql5.7.5以上才支持JSON类型。

  2. 字段描述格式:properties

    [
      {
    "field":"字段名",
    "type":"字段类型",
    "default":默认值,
    "label":"UI显示字符"
      }
    ]
  3. 商品详情设计:properties_detail

    MongoDB是没有表结构的,但是都应该包含一个字段,也就是goods的索引:id。

    {
      _id:ObjectId(),
      goods_id:Int64(),
      //........其他字段
    }

​ 再次通过观察上面设计的几个表结构,发现我们用了MongoDB动态表结构的特性,非常简单的实现了动态数据结构。

4.总结

​ 我们通过MongoDB的特性实现了存储异构数据。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

EMQX二次开发教程(高级篇) Previous
我的2019记录 Next