【问题标题】:Is this an reasonable use case for storing JSON in MySQL?这是在 MySQL 中存储 JSON 的合理用例吗?
【发布时间】:2013-09-19 15:58:52
【问题描述】:

我了解将 JSON 存储在 MySQL 列中通常被认为是一个“坏主意”,因为它变得难以维护并且不容易搜索或查询。但是,我觉得我在应用程序中遇到的场景是在我的 MySQL 表中存储 JSON 数据的合理用例。我确实在寻找答案,尤其是可以指出我可能忽略的任何困难的答案,或者是否有充分的理由避免我的计划,如果是,另一种方法。

手头的应用程序提供资源和库存管理,并支持构建程序集,其中可能包含无限数量的子程序集。

我有一个表格,其中包含项目的所有元数据,例如它们的名称、sku、零售价格、尺寸,以及对于这个问题最重要的:项目类型。项目可以是 partassembly。对于定义为程序集的项目,它们的内容存储在另一个表中,item_assembly_contents,其结构是相当预期的,使用parent_id 列将子级链接到父级。正如您所料,在任何时候,用户都可能决定在程序集中添加或删除项目,或者以其他方式修改程序集内容或将其完全删除。

这是上述表格描述的可视化表示,其中填充了数据,这些数据在组合时会创建一个包含另一个程序集的程序集。 使用上述结构,任何从items 表中删除的项目也将通过InnoDB ON DELETE CASCADEitem_assembly_contents 表中自动删除。

这是一个非常简单的 JSON 格式的程序集示例,展示了单个子程序集结构。

{
   "id":1,
   "name":"Fruit Basket",
   "type":"assembly",
   "contents":[
      {
     "id":10,
     "parent_id":1,
     "name":"Apple",
     "type":"part",
     "quantity":1
      },
      {
     "id":11,
     "parent_id":1,
     "name":"Orange",
     "type":"part",
     "quantity":1
      },
      {
     "id":12,
     "parent_id":1,
     "name":"Bag-o-Grapes",
     "type":"assembly",
     "quantity":1,
     "contents":[
        {
           "id":100,
           "parent_id":12,
           "name":"Green Grape",
           "quanity":10,
           "type":"part"
        },
        {
           "id":101,
           "parent_id":12,
           "name":"Purple Grape",
           "quanity":10,
           "type":"part"
        }
     ]
      }
   ]
}

水果篮是一个程序集,其中包含一个名为“Bag o Grapes”的子程序集。这一切都非常有效,直到考虑到订单和发货

以包含一个组件的出库货物为例。在任何时候,用户都必须能够看到程序集的内容,它们是在发货时定义的,这排除了简单地从itemsitem_assembly_contents 表,因为这些表可能在货件创建后已被修改。因此,装配内容必须与装运一起明确保存,以便以后可以查看它们,而与用户定义的库存中装配的状态或仅存在无关(即@ 987654333@表)。

将装配内容与装运内容一起存储让我有点困惑,在我看来,以 JSON 格式存储数据是一种可行的解决方案。了解有关此数据的以下几点至关重要:

  1. 它将用于搜索
  2. 任何 UPDATES 都会简单地覆盖该行的内容
  3. 它将最常用于填充客户端上的树视图,它将接受表中存在的 JSON,无需进行任何修改。

查看这张图片以获得(希望)更清晰的数据可视化:

问题

  1. 这是一个合理的用例吗?我的担心没有意义吗?
  2. 有什么我看过的东西可能会回来咬我吗?
  3. 您能否解释一下为什么我不应该继续我提出的架构,如果是的话......
  4. 您能提供一种替代方法吗?

与往常一样,非常感谢您抽出宝贵时间,请随时要求澄清或提供其他信息。

更新 根据@Rowland Shaw 的建议(如下),我提出了另一个建议的表结构,它使用与 order_assembly_contents 表的自反或“兔耳朵”关系。请看下图:

我觉得这比直接存储 JSON 更优雅,因为数据更具有关系性和数据库友好性。检索数据并为客户端生成数据也应该很容易!请提供有关上述结构的任何输入!

【问题讨论】:

  • 如果您不打算存储关系数据,为什么要使用关系数据库管理系统?为什么不将您的 JSON 文件(它们就是这样)存储在高度优化的文件存储数据库(即您的文件系统)中?
  • @eggyal 这是一个非常好的观点,也是我觉得我提出的表结构是一个丑陋的解决方案的原因之一。我想以关系方式存储这些数据,但是我正在努力解决如何以一种允许我这样做的方式来构建表。

标签: mysql json database-design extjs4 inventory-management


【解决方案1】:

通常,对于订购系统,我期望类似

产品 -- 订单

在您的情况下,您可以在您的产品上添加一个“兔子耳朵”关系来引用它自己。所以你的outbound_shipment_contents 失去了nametype 给新的product。然后,您可以根据需要递归构建要选择的项目树。

【讨论】:

  • 我想避免兔耳关系,因为这样做需要我牺牲parent_id -> order_contents.id的FK约束。需要以Order_Contents 表开头的原因是因为我不能指向主要的Product 表,因为当用户从他们的产品定义库中添加/删除产品时,该表总是会发生变化。所有订单和发货都必须保留它们包含的项目的记录,这些记录不能依赖于Product 表本身中数据的存在。我希望这是有道理的,非常感谢您的有用意见!
  • 我编辑了我的问题并使用自反关系添加了一个新的建议表结构。你觉得这是一种更优雅的方法吗?
  • 它看起来肯定比使用你的outbound_shipment_contents 本质上是我的OrderLine 和你的outbound_shipment_assembly_contents 是我的Product 存储 JSON 更优雅,尽管我也会有你的 Apple 和 Orange(只是没有孩子),这意味着你不需要(至少)outbound_shipment_contents 上的类型(可以说你可以通过它没有子行来推断它不是一个程序集)
  • 感谢您的帮助,我现在更有信心了!我已经接受了您的回答,因为它确实为我指明了正确的方向!
【解决方案2】:

这似乎是一个标准的物料清单问题,并且有很多关于 SQL 和物料清单模式的好文章。我会避免使用 JSON 存储,因为它确实使依赖本机 SQL 的任何报告和详细连接功能变得复杂。对于您的应用程序,您可以在数据访问层中为 UI 构建 JSON。

恕我直言:在关系数据库中保持数据干净、高度可访问和相关,在数据访问/低级别业务层重新用于应用程序。

【讨论】:

  • 感谢您提及材料清单,我现在正在阅读有关该主题的文章。我同意你的回答,我只是不确定如何根据我的需要构建数据库?有什么想法吗?再次感谢您!
  • 我将抽象架构以将订单视为产品和组件之间的外部参照表,并向其中添加数量属性。如果您的程序集将是递归的(我认为它们是递归的),那么您需要研究 SQL 的递归,重点是关系引擎的功能。我在一个表中看到一组相对静态的产品名称,在另一个表中看到初始组件加载的“默认”装配列表(或 Order 表中的属性驱动定义),然后是 Order 表来处理数量/内容编辑默认产品配置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-05
  • 1970-01-01
  • 2019-02-13
  • 1970-01-01
  • 2019-03-12
  • 1970-01-01
  • 2011-02-20
相关资源
最近更新 更多