图表数据的核心数据模型设计

Posted

技术标签:

【中文标题】图表数据的核心数据模型设计【英文标题】:Core Data model design for charting data 【发布时间】:2014-05-19 16:50:54 【问题描述】:

对于冗长的解释我很抱歉,但是我觉得有必要解释一下细节,以便我能够以最佳方式获得帮助,以创建正确的核心数据模型来满足我的要求。

我只是想找出创建数据模型的最佳方法,以便我能够以快速有效的方式实现以下目标,这在我当前的 mysql 设置中目前是不可能的。我正在使用 MySQL 从服务器返回所有值,但现在希望使用 CoreData 来缓存这些数据,并且只下载新的日期数据。

我有一个存储这样的数据集的数据库:


    "Agent_Id" = 32;
    "Order_FinalisedDate" = "2014-05-17 03:39:54";
    "Order_Id" = 2596;
    "Order_ReferenceNumber" = "Pavan/0905/016";
    "PieChart_Id" = 13585;
    "PieChart_QuantityATOP" = 150;
    "PieChart_TotalAmount" = 52500;
    "Product_Id" = 20;

每次加载 viewController 时,我都有 13,585 个这样的数据集从服务器飞入。处理从服务器检索到的数据需要 1 分半钟。这是非常低效的,我试图创建一个核心数据模型来帮助我处理流程以显着减少时间。

这是在没有 Core Data 的情况下发生的当前过程

    我只对过去 12 个月的滚动感兴趣,就像银行如何退回过去 12 个月的帐户一样。因此,我从服务器获取了一个 JSON 格式的实时动态数组,将它们很好地复制到其自定义的 BankDateDataModel 数据模型中,该数组名为 monthsChartDataDictionary,该数组以 yyyy-MM 的这种格式存储数据。

    李>

    然后,我会检查所有的销售,如果它的日期可以与 monthsChartDataDictionary 数组中的匹配日期相关联,则对其进行抓取和分类。

    //Go through each data set
    for(id key in JSONDictionary)
        //First lets store each data set which we will use for another process.
        PieChartSliceDataModel *pcs = [[PieChartSliceDataModel alloc] initWithJSONData:key];
        [allPieChartDataArray addObject:pcs];
    
        /**
            Check to see if we have a date entry in the format of `yyyy-MM`
            If there is a 
        */
    
        if([monthsChartDataDictionary objectForKey:pcs.PCS_StringOrderFinalisedDate])
            [[monthsChartDataDictionary objectForKey:pcs.PCS_StringOrderFinalisedDate] addObject:pcs];
        
    
    

    这本质上是创建的 - 月ChartDataDictionary。一个字典,其键格式为yyyy-MM,并在其关联键中包含一组数据集。

       //An nsdictionary holding over 13,500 elements.
        "2013-05"=(..,..,..);
        "2013-06"=(..,..,..);
        "2013-07"=(etc);
        "2013-08"=();
        "2013-09"=();
        "2013-10"=();
        "2013-11"=();
        "2013-12"=();
        "2014-01"=();
        "2014-02"=();
        "2014-03"=();
        "2014-04"=();
        "2014-05"=();
    
    

    然后运行一个 for 循环来同时完成两件事,请参见下面的 a) 和 b):

    a) 对于 monthsChartDataDictionary 字典中的每个月,我通过统计每个数据集的 PieChart_TotalAmount 来获得该月的总销售额。这用于创建显示全年总销售额的折线图。

    b) 制作了一个新字典 - finalPieChartData,其中每个键的格式为yyyy-MM,存储的值是一个产品数组,显示每个产品的总销售额。这样可以制作一个饼图,显示在任何给定月份内的产品销售情况。其中12sp B - 250 是产品名称。

如何在核心数据模型中最好地表示所有这些?

我在想是否有办法存储所有必需的数据,包括总销售额,并在给定月份内将不同产品的销售额分开......全部存储在核心数据中......或者最好在什么时候进行这些计算它们是从核心数据数据库中返回的,我猜这只会导致更多延迟。

到目前为止我有这个:

我创建这个的逻辑基于以下想法:

    我可以拥有一个存储所有单独数据集的数据库 另一个存储折线图每月总销售额的表,所以我不必继续执行计算,除非我需要更新最近一个月的销售数据,因为我获得了仍在发生的新销售同月。 除了每月销售核心数据模型之外,还会有一组饼图切片,它们表示任何特定月份内每个产品 ID 的总销售额。这意味着我不必一次又一次地处理计算。

这是正确的吗?有没有一种有效的方法来存储所有内容?

更新 1:更新了提议的核心数据模型,以便在应用程序中实现后提高效率

【问题讨论】:

这不是一个固执己见的问题。我正在寻找核心数据模型设计的好方法。 您对优化模型以使 UI 响应和应用程序的内存占用最小化特别感兴趣,对吧?因为您提到了缓慢的获取,但没有提及用于此的核心数据堆栈...是否创建临时上下文,以及是否使用父子等。但是核心数据堆栈和后台获取与此问题是分开的对吧? 嘿@stevesliva,我没有使用核心数据堆栈atm。需要很长时间的是我在第 1 步中提到的。将json 数据处理为nsdictionary,另一个需要很长时间的部分是第 2 步,我创建了所有饼图数据。因此,我特别要求构建数据模型的最佳方法,以便所有数据都已处理好,可以使用所有预先计算的值进行检索,因为它们将像这样保存到数据存储中,然后只需要被提出。续。 续。因此,为什么我试图找到最好的方式来存储所有需要的数据,这样当我检索数据时,我不需要做任何处理。 @stevesliva,有人吗?! 【参考方案1】:

NSDateFormatter 对性能非常有害。如果您在映射期间第一次使用它,则应尽量减少它的分配。如果你不想,你可以提供第一步的代码 sn-p

您也可以在 xcode product-profile-time profiler 中使用。它可以帮助您跟踪低性能操作。

关于使用网络服务和核心数据,请查看restKit

您也可以在 raywenderlich 的此链接下获得有关使用 Web 服务和核心数据的建议 part 1 part 2

【讨论】:

您好,感谢您的发帖。我是创建 Web 服务的人,我也熟悉与 restful 服务器通信。我知道缓慢的过程发生在哪里。我还没有使用NSDateFormatters。请再次仔细阅读我的帖子。它需要永远的原因是,在第一步中,我分配了超过 13,000 个对象并将其存储在一个数组中,然后对该数组进行计算以创建我的饼图数据和我的折线图数据。我分离数据,以便对象显示在正确的月份类别和正确的饼图中。续。 我要求您记下:数据集keys,以及我如何使用销售数据(其中超过 13,000 个)来创建我需要的图表,但随后有存储这些值的有效数据模型;每个月的计算值;和饼图值,这样我就不需要不断迭代每个数据集来计算每次需要显示图形时需要的图形数据。如果您在记下数据集并了解所有数据的计算方式后可以查看数据模型,那么解释存储所有数据的正确方法会很棒。 @Pavan 谢谢你的澄清。你能添加第一步的代码sn-p吗?或者如果它是一大块代码添加部分,这是您认为最关键的部分 大声笑,相信我它不会对你有帮助,因为它甚至与问题无关。它也需要不到一毫秒的时间。它所做的只是接收一个包含 12 个元素的数组(即从今天开始的最近 12 个月的字符串日期),该数组存储在一个名为 monthsChartDataDictionary 的字典变量中。看一下字典的第 2 步。代码片段非常小。它实际上非常微不足道。然后它直接移动到第 2 步。 请检查我最后的评论,伙计。【参考方案2】:

对于订单输入系统,您需要在服务器端有一个本月至今 (MTD) 和本年至今 (YTD) 表,其中包含以下字段:更新日期、总销售额和订单总数量。表格应随订单实时更新或每晚按批次更新。该应用程序只需要下载 MTD 数据即可生成所需的销售图表。为 MTD 表创建本地存储可能有一些价值,但随着数据量的减少,可能没有必要。

如果需要过滤,请考虑为所需的过滤器创建单独的表 (MTD),而不是尝试将应用中的所有内容制成表格并重新计算。

【讨论】:

感谢您的发帖,但是,我确实觉得按照这种方法在服务器端会变得非常混乱。在我的应用程序中必须有我想要的灵活性级别。无需根据选择的过滤器一次又一次地传输数据。这不是解决问题的方法。这就是为什么我们有核心数据,以允许本地存储。这个问题再次出现在我的帖子中。 数据传输非常昂贵。在过去的 30-40 年中,订单输入系统一直使用 MTD 和 YTD 表构建。银行账户也以同样的方式完成。如果表是实时更新的(当交易进入时(在过去,这些 MTD 是在交易日志中的一天结束时分批的),这不会很混乱。如果你不是构建订单输入系统的人 - 为什么不你先问,他们可能已经准备好了这些桌子。如果是现成的包装,那么这些东西就已经准备好了。 如果您担心过滤器 - 识别它们并将其作为单独的字段插入到 MTD 表中,这些字段总计为总金额和总数量。这将解决您的复杂性问题。你也可以在 ios 设备上做同样的事情,但你需要记住,同样的工作会在每台设备上复制,对我来说这是糟糕的设计。

以上是关于图表数据的核心数据模型设计的主要内容,如果未能解决你的问题,请参考以下文章

车载SOA软件架构设计

核心数据设计:更好的 1 模型和 2 商店或 2 模型和 2 商店?

创建核心数据模型设计的最佳方法是啥?

核心数据模型设计 - 更改“实时”对象也会更改保存的对象

详解Java设计模式之观察者模式(Observer Pattern)

详解Java设计模式之观察者模式(Observer Pattern)