据我所知,将JSON存储在MySQL列中通常被认为是一个“坏主意”,因为它很难维护,不易搜索或查询。但是,我觉得我在我的应用程序中遇到的场景是一个合理的用例,用于在我的MySQL表中存储JSON数据。我确实在寻找答案,特别是可以指出我可能忽略的任何困难的答案,或者是否有任何充分的理由要避免我的计划,如果有的话,这是另一种方法。
手头的应用程序提供资源和库存管理,并支持构建可能包含无数个子装配的装配体。
我有一个表格,其中包含所有项目的元数据,例如名称,sku,零售价格,维度,最重要的是这个问题:项目类型。项目可以是部分或程序集。对于定义为程序集的项目,其内容存储在另一个表格item_assembly_contents
中,其结构非常期望,使用parent_id
列将子项链接到父项。正如您所料,用户可以随时决定在程序集中添加或删除项目,或以其他方式修改程序集内容或将其完全删除。
以下是上表描述的直观表示,其中填充了数据,在编写时,创建包含另一个程序集的程序集。
使用上述结构,从
items
表中删除的任何项目也将通过InnoDB item_assembly_contents
在ON DELETE CASCADE
表中自动删除。
这是一个非常简单的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”的子装配体。这一切都非常有效,直到考虑订单和货件。
例如,包含装配的出库货件。在任何时候,用户必须能够看到装配的内容, ,因为它们是在发货时定义的 ,这排除了简单地从中检索数据items
和item_assembly_contents
表,因为这些表可能在创建货件后已被修改。因此,必须在装运时明确保存装配内容,以便以后查看它们,而不依赖于用户定义的库存中的装配状态或仅存在(即{ {1}}表)。
它正在将装配内容与我有点困惑的装运内容一起存储,在我看来,在JSON中存储数据是一个可见的解决方案。了解有关此数据的以下几点至关重要:
请参阅此图片以获得(希望)更清晰的数据可视化:
问题
与往常一样,非常感谢您的时间,请不要犹豫,要求澄清或提供更多信息。
更新
根据{{3}}的建议(下面),我提出了另一个建议的表结构,它使用了与order_assembly_contents表的反身或“兔子耳”关系。请看下图:
我觉得这比直接存储JSON更优雅,因为数据更具关系性和数据库友好性。检索数据并为客户端创建数据也应该很容易!请提供有关上述结构的任何意见!
答案 0 :(得分:1)
通常,对于订购系统,我希望有类似
的东西Product -< OrderLine >- Order
在您的情况下,您可以在产品上添加“兔子耳朵”关系以引用自身。因此,您的outbound_shipment_contents
会丢失name
,type
到新的product
。然后,您可以递归地构建要根据需要选择的项目树。
答案 1 :(得分:1)
这似乎是一个标准的物料清单问题,有很多关于SQL和物料清单模式的好文章。我会避免使用JSON存储,因为它确实使依赖于本机SQL的任何报告和详细加入功能变得复杂。对于您的应用程序,您可以在数据访问层中为UI构建JSON。
恕我直言:在关系数据库中保持数据清晰,高度可访问和关系,为数据访问/低级别业务层的应用程序重新调整用途。