静态数据应该存储在数据库中还是其他地方?


20

我目前正在开发某些软件,但不确定该采用哪种方法。我有一些数据要存储在移动设备上的某个地方。数据将永远不会改变,并具有层次关系,并将用于填充显示。有相当数量的此数据。

我有以下选择:

  1. 一组枚举/对象
  2. XML文件
  3. 嵌入式SQLite数据库

在这种特殊情况下,我认为enums选项的工作量最少,但是我从这样的代码中嵌入的数据中获得了味道。

我认为XML文件最有意义,但是解析它会浪费资源,因为它永远不会改变。

数据库应该不会对性能造成太大的影响,但是对于静态数据来说似乎有点过分了。

这里正确的设计路径是?

注意: “永不更改”是指更改很少。有问题的数据是一组政府标准的模型,因此它们将来很可能会发生变化,但它不会定期更新,也不会自动更新我们的软件,因为标准的变化很可能会触发我们需求的变化。


2
每种方法之间在性能方面的时间差异是多少?您是否曾经测试/基准测试它们?
Mahdi 2014年

1
“很少更改”-运行时是否需要更改?在应用程序启动时?还是可以接受的新版本?

在运行时或启动期间,它永远不会改变。可以接受新的建造
CurlyPaul 2014年

我认为这里没有明确的“应该”。您几乎没有提供有关数据量,数据性质及其使用方式的信息。过去,我已经完成了所有上述操作……您走的路线实际上取决于您
GrandmasterB 2014年

将数据嵌入为枚举/对象不一定是错误的,它很可能是最简单,最干净和最正确的。这完全取决于将来可能导致数据更改的原因。
JacquesB

Answers:


18

我会为此使用一个对象。

您说数据永远不会改变,因此您可以轻松地将其存储在应用程序中。该数据库将过大并增​​加大小。
XML文件也会有点过大,并且还会增加大小。

因此,我认为最好的选择是枚举或对象。


2
这就是我趋于诚实的做法,我唯一不喜欢的就是将数据与代码混合在一起。有时候,我不得不承认,最好的路径并不总是与我的强迫症虽然适合
CurlyPaul

一个枚举没什么不好;)您拥有什么样的数据?
Knerd 2014年

数据正在对一组问题进行建模,并按类别和子类别进行组织。问题也有3种可能的答案和一些参考数字。该项目使用Java编写,因此enum对象非常适合此操作。我认为您是对的,这将是最容易实现且最有意义的
做法

11

它永远不会改变,还是会改变?这是您真正得到良好回答之前必须回答的问题。

永不更改的静态数据(例如,星期几的名称)可以在代码中使用;

实际上永不更改的数据(例如,您的服务器dns名称)也适合放入代码中,如果需要更改,那么这种代码很少可以更新。

不变的数据,但是可能(例如,定期刷新之间的时间延迟)的数据最好在易于更改的位置(例如本地配置存储(sqlite或xml,没有任何实际区别))

几乎不需要担心存储-如果它从未更改过或几乎没有更改过,则可以在程序启动时全部读取并存储为程序数据。如果确实需要更改(在极少数情况下),则重新启动应用程序没什么大不了的。


我添加了一些有关这种情况下“从不”发生频率的信息
CurlyPaul 2014年

@CurlyPaul将它们绑定在代码中,如果它们更改了,您可能仍然不得不更新代码。仅在将它们简化编码/测试的情况下,才将它们放在sqlite / xml数据库中。
gbjbaanb 2014年

“无需更改的静态数据(例如,星期几的名称)可以在代码中输入”,即使那样,您也可能出错:请等到您的应用程序国际化。工作日名称并非一成不变。
Pieter B

@PieterB这只是我脑海中的一个例子。“一周中的天数”对您来说是一个比较难挑剔的例子吗?
gbjbaanb 2014年

@gbjbaanb等到我们开始殖民其他星球。那你要怎么办 / s
MiniRagnarok 2014年

5

通常,“永不更改”的内容是最先更改的...
无论您使用数据库还是其他外部系统(例如配置文件),只要可以在需要时轻松快速地访问它,就无关紧要。
如果我已经有一个数据库,我倾向于使用数据库表,并且这很有意义(例如,数据可能需要由对应用程序部署到的服务器没有文件系统访问权限的人或在多台机器上运行的人来更改。并且配置之间必须保持同步)。
当然,数据库不能容纳所有内容。例如,数据库凭据将需要存储在其他位置,很可能是配置文件。


我添加了一些有关这种情况下“从不”发生频率的信息。感谢您的输入
CurlyPaul

让我们创建一个表“ genders”来存储性别M(ale)和F(emale),它们会改变吗?
Martin Pfeffer

4

要求提供任何数据的问题不是它是否会改变。您可能不知道,即使您知道,答案也可能会误导您。

要问的问题是,何时更改,应该更改:

  • 软件作者:将其放入代码中
  • 最终用户:在GUI上有一个选项
  • 其他人(例如系统集成商,国际化服务等):数据库表,文件或其他有意义的文件(有时包括扩展API)。

通常,星期二应该是一个枚举,而不是因为它永远不会改变。但是,因为如果一个疯狂的独裁者确实在星期二负责并要求以他的名字命名,那么作为软件作者的您将不得不对其进行更改(或被视为鲨鱼)。

您不希望所有用户都必须深入研究配置文件或模糊数据库表以避免这种命运...


疯狂的独裁者,疯狂的项目经理,疯狂的客户... pff。
Mahdi 2014年

这是正确的答案!
JacquesB

2

即使您的数据在现实世界中表示的实体可能不需要更改,您的数据也有可能需要更改。您需要确定是否值得添加一个单独的某种文本文件,而无需更新整个应用程序即可对其进行更新。

例子:

  1. 印刷错误/拼写错误。
  2. 意外遗漏。
  3. 用另一种语言提供数据。
  4. 为用户提供一种进行自己的更改的方法。

任何其他类型的数据结构更改可能都需要对应用程序进行更新,所以这没有好处。


1

我最初是在stackoverflow上这个问题写这个答案的,但是我认为同样的答案也适用于这个问题。

Mathias Verraes的一篇文章在这里谈论您的问题。他谈到了将模型中的值对象与服务UI的概念分开。

当被问及是否将国家建模为实体或价值对象时,引用该文章:

将国家/地区建模为实体并将其存储在数据库中没有本质上的错误。但是在大多数情况下,这会使事情变得复杂。国家不经常改变。一个国家的名称更改时,实际上,从所有实际目的来看,它都是一个新国家。如果某个国家/地区不再存在,则不能简单地更改所有地址,因为该国家/地区可能已分为两个国家。

他提出了另一种方法来引入一个新概念,称为AvailableCountry

这些可用的国家/地区可以是数据库中的实体,JSON中的记录,甚至可以是代码中的硬编码列表。(这取决于企业是否希望通过UI轻松访问它们。)

<?php

final class Country
{
    private $countryCode;

    public function __construct($countryCode)
    {
        $this->countryCode = $countryCode;
    }

    public function __toString()
    {
        return $this->countryCode;
    }
}

final class AvailableCountry
{
    private $country;
    private $name;

    public function __construct(Country $country, $name)
    {
        $this->country = $country;
        $this->name = $name;
    }

    /** @return Country */
    public function getCountry()
    {
        return $this->country;
    }

    public function getName()
    {
        return $this->name;
    }

}

final class AvailableCountryRepository
{
    /** @return AvailableCountry[] */
    public function findAll()
    {
        return [
            'BE' => new AvailableCountry(new Country('BE'), 'Belgium'),
            'FR' => new AvailableCountry(new Country('FR'), 'France'),
            //...
        ];
    }

    /** @return AvailableCountry */
    public function findByCountry(Country $country)
    {
        return $this->findAll()[(string) $country];
    }
}

因此,似乎存在第三种解决方案,即将查找表建模为值对象和实体。

顺便说一句,请确保您在评论部分中查看有关该文章的认真讨论


-1

注意事项:

  • 数据有多静态?如果它永远不会改变,那么它应该存在于对象中。为了更改数据,您可能必须重新编译和重新部署。您是否愿意对较小的更改进行重新部署?

  • 如果它是一个Web应用程序,并且已将其作为web.config的一部分,那么您对数据进行更改时对重新启动应用程序感到满意吗?

  • 如果将其放入数据库中,则始终可以将其缓存在客户端(桌面应用程序)或服务器端(服务或网站)上。数据库可能是IMO的一个很好的解决方案。


关于问询者在评论中提供了关于数据静态性的说明:“在运行时或启动期间它永远不会改变。可以接受新的构建”,请考虑编辑答案以解决这一问题
2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.