json - vue js 数据设计策略 - 来自 API 的复杂 JSON 对象或具有 PK/FK 关系的简单 JSON 对象
问题描述
我正在设计一个 vue.js (vue2) 应用程序,它需要从 3NF 中的 4 个数据库表派生的复杂数据集。将使用 axios 将数据调用到 PHP 端点,该端点将从本地 MSSQL 获取数据。从概念上讲,数据的形状如下:
{
Collection-A [
{
Obj1:{
Obj1.field1,
Obj1.field2
},
Obj2:{
Obj2.field1:,
Obj2.field2:
},
Collection-B:[
{
CollB.field1,
CollB.field2,
CollB.Collection-C:[
{
CollC.field1:,
CollC.Collection-D:[0,1,2],
CollC.Obj3:{
Obj3.field1:,
Obj3.field2:,
Obj3.field3
},
CollC.Obj4:{
Obj4.field1:
Obj4.field2:
}
}...repeat Collection-C
]
}...repeat Collection-B
]
}..repeat Collection-A
]
}
我的问题是如何最好地为性能、理解和重用数据建模。
- 选项 1 是将四个集合提取到 data() 对象中的不同数组中,其中包含 PK 和 FK 字段,然后使用 .map 和 .filter 查找相关记录。这将避免对象内重复数据的嵌套,因此有利于内存,但需要计算上昂贵的查找。它还具有保持 API 简单的好处。
- 选项 2 是以简单形式提取数据,然后构建复杂对象进行渲染。这会导致双倍存储,我必须等待所有 axios 请求完成:要么使用 4 次调用,要么从一次调用 Collection-A 数据开始,然后对所需的每一级数据进行多次调用
- 选项 3 是进行单个 API 调用并让 PHP 构造数据。这将需要 PHP 对数据库进行四次调用(或对每个嵌套对象进行迭代调用),并且将是单线程的,因此可能会很慢,并且在构建 PHP 对象之前我不会取回任何数据。
- 选项 4 是让数据库引擎构建复杂对象,随着引擎的优化,该对象的计算速度可能会更快。不幸的是,我的 MSSQL 版本只支持 FOR XML 而不是 FOR JSON,所以我仍然需要在 PHP(或使用 js 库)中将 XML 转换为 JSON,或者使用游标和 BCP 构建 JSON 对象
选项 1 或 2 感觉是最干净的解决方案,因为 API 可重用且易于测试。不幸的是,GraphQL 在我当前的环境中不是一个选项。任何建议将不胜感激。
解决方案
很难给出任何具体建议,因为您的数据模型示例非常简单,并且缺少一些重要信息,例如:
- 数据的基数是多少?Collection-B/C 中只有少数对象被 Collection-A 中的许多对象使用吗?(换句话说,去规范化时数据膨胀了多少)
- 您如何在应用程序中使用数据?也只是查看或更新?是否需要更新 B/C 集合对象?
- 在任何给定时间,您的应用程序需要整个数据集的多少?
- 用例呢?感知绩效对您来说有多重要?是否可以仅加载和显示集合 A 中的对象(在某种网格中)并在需要时在后台或按需加载其余数据?
您需要考虑所有要求(或为自己设置一些要求),而不仅仅是技术方面。
无论如何,这里有一些想法:
- 鉴于您的数据已经以正常形式存储,选项 1 感觉最好。例如,您可以使用Vuex ORM 之类的库来简化您的工作(如果不愿使用“另一个 3rd 方库”,请单独考虑 Vuex - 它由 Vue 核心团队维护)。
- 如果需要更新集合 B/C 对象,我强烈推荐这种方法(因为当您需要更新相同数据的多个副本时会很困难)
- 内存中的数据表示和“传输中”是不同的东西。您可以决定将数据保持为正常形式,但出于性能原因将其非规范化加载(Vuex ORM 使这变得简单- 也可用于测试)
- 如果您一次不需要所有数据,请考虑使用延迟加载
推荐阅读
- python - 我有 PyQt4 GUI,我想以复选框的形式列出文件。但复选框仅显示目录中的最后一个文件
- c++ - Docker 构建抛出错误“致命错误:json/json.h:没有来自 ubuntu:14.04 的此类文件或目录”
- api - oAuth 返回 400 错误请求
- ios - 使用 NSNetServices 类设置多个 iOS 设备之间的通信
- reactjs - catching error on successful api post - Axios
- spring - Spring 集成 - 重试在异常情况下建立连接
- c# - 如何在 xunit 中模拟 Db 连接?
- javascript - Javascript - 仅保留给定所需属性列表的值
- java - Spring Batch 内存泄漏 - 使用 JpaItemWriter 将 CSV 保存到数据库
- android - 根据父宽度设置recyclerview子宽度相等