【发布时间】:2013-09-19 15:58:52
【问题描述】:
我了解将 JSON 存储在 MySQL 列中通常被认为是一个“坏主意”,因为它变得难以维护并且不容易搜索或查询。但是,我觉得我在应用程序中遇到的场景是在我的 MySQL 表中存储 JSON 数据的合理用例。我确实在寻找答案,尤其是可以指出我可能忽略的任何困难的答案,或者是否有充分的理由避免我的计划,如果是,另一种方法。
手头的应用程序提供资源和库存管理,并支持构建程序集,其中可能包含无限数量的子程序集。
我有一个表格,其中包含项目的所有元数据,例如它们的名称、sku、零售价格、尺寸,以及对于这个问题最重要的:项目类型。项目可以是 part 或 assembly。对于定义为程序集的项目,它们的内容存储在另一个表中,item_assembly_contents,其结构是相当预期的,使用parent_id 列将子级链接到父级。正如您所料,在任何时候,用户都可能决定在程序集中添加或删除项目,或者以其他方式修改程序集内容或将其完全删除。
这是上述表格描述的可视化表示,其中填充了数据,这些数据在组合时会创建一个包含另一个程序集的程序集。
使用上述结构,任何从items 表中删除的项目也将通过InnoDB ON DELETE CASCADE 在item_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”的子程序集。这一切都非常有效,直到考虑到订单和发货。
以包含一个组件的出库货物为例。在任何时候,用户都必须能够看到程序集的内容,它们是在发货时定义的,这排除了简单地从items 和 item_assembly_contents 表,因为这些表可能在货件创建后已被修改。因此,装配内容必须与装运一起明确保存,以便以后可以查看它们,而与用户定义的库存中装配的状态或仅存在无关(即@ 987654333@表)。
将装配内容与装运内容一起存储让我有点困惑,在我看来,以 JSON 格式存储数据是一种可行的解决方案。了解有关此数据的以下几点至关重要:
- 它将不用于搜索
- 任何 UPDATES 都会简单地覆盖该行的内容
- 它将最常用于填充客户端上的树视图,它将接受表中存在的 JSON,无需进行任何修改。
查看这张图片以获得(希望)更清晰的数据可视化:
问题
- 这是一个合理的用例吗?我的担心没有意义吗?
- 有什么我看过的东西可能会回来咬我吗?
- 您能否解释一下为什么我不应该继续我提出的架构,如果是的话......
- 您能提供一种替代方法吗?
与往常一样,非常感谢您抽出宝贵时间,请随时要求澄清或提供其他信息。
更新 根据@Rowland Shaw 的建议(如下),我提出了另一个建议的表结构,它使用与 order_assembly_contents 表的自反或“兔耳朵”关系。请看下图:
我觉得这比直接存储 JSON 更优雅,因为数据更具有关系性和数据库友好性。检索数据并为客户端生成数据也应该很容易!请提供有关上述结构的任何输入!
【问题讨论】:
-
如果您不打算存储关系数据,为什么要使用关系数据库管理系统?为什么不将您的 JSON 文件(它们就是这样)存储在高度优化的文件存储数据库(即您的文件系统)中?
-
@eggyal 这是一个非常好的观点,也是我觉得我提出的表结构是一个丑陋的解决方案的原因之一。我想以关系方式存储这些数据,但是我正在努力解决如何以一种允许我这样做的方式来构建表。
标签: mysql json database-design extjs4 inventory-management