代码之家  ›  专栏  ›  技术社区  ›  dnolan

如何在数据库中构造配置数据?

  •  23
  • dnolan  · 技术社区  · 16 年前

    在数据库中存储应用程序配置数据的首选方法是什么?从我自己做过这件事开始,我就用了两种方法来做这件事。

    1. 您可以创建一个存储键/值对的表,其中键是配置选项的名称,值是其值。专业的这是添加新的值很容易,您可以使用相同的例程来设置/获取数据。缺点是您有非类型化的数据作为值。
    2. 或者,您可以硬编码一个配置表,其中每个列都是值的名称及其数据类型。这样做的缺点是需要更多的维护来设置新的值,但是它允许您输入数据。

    在使用了这两种方法之后,我的首选项在于第一个选项,因为它设置起来更快,但是它也更具风险,并且在查找数据时会降低性能(稍微)。有人有其他方法吗?

    更新

    有必要将信息存储在数据库中,因为如下面所述,程序的多个实例可能需要以相同的方式配置,以及可能使用相同值的存储过程。

    18 回复  |  直到 10 年前
        1
  •  20
  •   RB.    16 年前

    您可以展开选项1以获得第三列,并给出数据类型。应用程序不能使用此数据类型列来强制转换值。

    但是,如果配置文件不是一个选项,我会选择选项1。选项1的另一个优点是,您可以将其读取到字典对象(或等效对象)中,以便在应用程序中使用。

        2
  •  9
  •   Hugo    16 年前

    由于配置通常可以存储在文本文件中,因此字符串数据类型应该足以存储配置值。如果您使用的是托管语言,则是代码知道数据类型应该是什么,而不是数据库。

    更重要的是,考虑这些配置:

    • 等级制度 :显然,配置将受益于 等级制度
    • 版本控制 :考虑能够回滚到在某个日期生效的配置的好处。
    • 分布 :有时,能够集群应用程序可能会更好。一些属性可能是集群中每个节点的本地属性。
    • 文档 :根据您是否有Web工具或其他工具,最好将有关属性的文档存储在使用它的代码附近。(代码注释非常适合这样做。)
    • 通知 :代码如何知道配置存储库中的某个地方发生了更改?

    就我个人而言,我喜欢一种处理配置的反向方式,在这种方式中,配置属性被注入到不知道值来自何处的模块中。这样,配置管理系统可能非常复杂,也可能非常简单,这取决于您(当前)的需求。

        3
  •  4
  •   johnstok    16 年前

    我使用选项1。

        4
  •  4
  •   Haoest    16 年前

    使用db作为配置数据似乎有点过分。

    编辑(抱歉,评论框太长): 当然,对于如何实现程序的任何部分没有严格的规则。为了争论,一字槽螺丝刀在一些飞利浦螺丝上工作!我想在知道你的情况之前我判断得太早了。

    关系数据库在海量数据存储中表现出色,可以快速存储、更新和检索,因此,如果配置数据不断更新和读取,那么一定要使用db。

    另一个DB可能有意义的场景是,当您有一个服务器场,希望您的数据库存储中心配置时,但是您可以对指向XML配置文件的共享网络驱动器执行相同的操作。

    当配置是层次结构时,XML文件更好。您可以轻松地组织、定位和更新所需内容,并且为了获得额外的好处,您可以将配置文件与源代码一起进行版本控制!

    总之,这完全取决于如何使用配置数据。

    最后,我对你的申请知之甚少。我相信你能做出正确的决定。

        5
  •  3
  •   Ady    16 年前

    我想这更像是一个民意测验,所以我会说列方法(选项2)。但是,这将取决于配置更改的频率、动态性以及数据量等。

    我当然会将这种方法用于用户配置/首选项等。

        6
  •  3
  •   Elliot    16 年前

    我的项目使用的数据库表有四列:

    1. ID[PK ]
    2. 作用域(默认“应用程序”)
    3. 设置
    4. 价值

    范围为“应用程序”的设置是全局设置,例如最大同时用户数。

    每个模块都有自己的基于作用域的;所以我们的resultsloader和userloader有不同的作用域,但都有一个名为“inputpath”的设置。

    默认值要么在源代码中提供,要么通过IOC容器注入。如果数据库中没有注入或提供任何值,则使用代码中的默认值(如果存在)。因此,默认值永远不会存储在数据库中。

    这对我们来说很好。每次备份数据库时,我们都会得到配置的副本,这非常方便。两者总是同步的。

        7
  •  2
  •   JacquesB    16 年前

    选择2。 选项1实际上是在数据库之上实现数据库的一种方法,这是一种众所周知的反模式,从长远来看,这会给您带来麻烦。

        8
  •  2
  •   jakber    16 年前

    我至少还能想到两种方法:

    (A)创建一个包含键、字符串值、日期值、int值、实值列的表。保留未使用的类型为空。

    (B)使用XML、YAML或JSON之类的序列化格式,并将其全部存储在一个BLOB中。

        9
  •  0
  •   Dov Wasserman    16 年前

    您将应用程序连接到数据库所需的配置设置存储在哪里?

    为什么不在那里存储其他配置信息呢?

        10
  •  0
  •   James Curran    16 年前

    我会选择选项1,除非配置选项的数量非常小(7个或更少)

        11
  •  0
  •   Jeb    16 年前

    在我的公司,我们正在努力使用选项一(一个简单的字典式的表格)和一个转折点。我们允许使用包含要替换的配置变量名称的标记进行字符串替换。

    例如,该表可能包含行(“数据库连接字符串”、“jdbc://%host%…”)和(“host”、“foobar”)。通过简单的服务或存储过程层封装,可以实现非常简单但灵活的递归配置。它支持我们需要多个独立的环境(dev、test、prod等)。

        12
  •  0
  •   rmeador    16 年前

    我以前用过1和2,我认为它们都是糟糕的解决方案。我认为选项2更好,因为它允许输入,但比选项1难看得多。我遇到的最大问题是对配置文件进行版本控制。您可以使用标准版本控制系统很好地版本化SQL,但是合并更改通常是有问题的。如果有机会这样做“正确”,我可能会创建一组表,每种类型的配置参数一个(不一定是每个参数本身),从而在适当的情况下获得键入的好处和键/值范式的好处。您还可以通过这种方式实现更高级的结构,例如列表和层次结构,然后应用程序将直接查询这些结构,而不必加载配置,然后在内存中以某种方式转换它。

        13
  •  0
  •   Andrew Cowenhoven    16 年前

    我投票赞成第二种选择。易于理解和维护。

        14
  •  0
  •   Doug L.    16 年前

    选项1适用于易于扩展的中央存储位置。除了RB、Hugo和Elliott等人的一些很棒的专栏建议之外,您还可以考虑:

    在用户字段甚至用户/机器字段中包括全局/用户设置标志(用于机器特定的UI类型设置)。

    当然,这些数据可以存储在本地文件中,但是由于您无论如何都在使用数据库,因此在调试时这些数据可以作为用户的别名—如果与bug设置相关,这一点很重要。它还允许管理员在必要时管理设置。

        15
  •  0
  •   Tom    16 年前

    我在SQL Server中混合使用了选项2和XML列。 您也可以不添加检查约束来将表保持在一行。

    CREATE TABLE [dbo].[MyOption] (
      [GUID] uniqueidentifier CONSTRAINT [dfMyOptions_GUID] DEFAULT newsequentialid()  ROWGUIDCOL NOT NULL,
      [Logo] varbinary(max) NULL,
      [X] char(1)  CONSTRAINT [dfMyOptions_X] DEFAULT 'X' NOT NULL,
      CONSTRAINT [MyOptions_pk] PRIMARY KEY CLUSTERED ([GUID]),
      CONSTRAINT [MyOptions_ck] CHECK ([X]='X')
    )
    
        16
  •  0
  •   poop-deck    15 年前

    对于与任何DB表都没有关系的设置,如果需要DB处理这些值,我可能会使用EAV方法。否则,如果一个序列化字段值实际上只是应用程序代码的存储,那么它就是好的。

    但是,对于单个字段存储数据库使用的多个配置设置的格式呢?

    每个用户都有一个字段,其中包含与他们的MessageBoard视图相关的所有设置(如默认排序顺序、阻止的主题等),另一个字段可能包含他们的主题的所有设置(如文本颜色、背景颜色等)。

        17
  •  0
  •   Zardoz    14 年前

    在关系数据库中存储层次结构和文档是疯狂的。首先,你要么把它们粉碎,要么在以后的某个阶段重新组合。或者是在一个小圈子里,更愚蠢的是。

    不要将关系数据库用于非关系数据,该工具不适合。为此考虑MongoDB或CouchDB之类的东西。无模式无关系数据存储。将其存储为JSON。如果它以任何方式连接到客户机,请使用XML作为服务器端。

    CouchDB为您提供开箱即用的版本控制。

        18
  •  0
  •   Moses    14 年前

    除非有充分的理由,否则不要将配置数据存储在数据库中。如果您确实有一个非常好的理由,并且绝对确定要这样做,那么您应该将它存储在数据序列化格式中,如JSON或YAML(而不是XML,除非您实际上需要一种标记语言来配置您的应用程序——相信我,您不需要)。然后您就可以读取字符串,并使用您使用的任何语言的工具来读取和修改它。使用时间戳存储字符串,并且您有一个简单的版本控制方案,能够在非常简单的系统中存储分层数据。即使您不需要分层配置数据,至少现在如果您将来需要它,您也不必更改配置接口来获取它。当然,您将失去对配置数据进行关系查询的能力,但是如果您正在存储 那个 很多配置数据,那么你可能做了一些非常错误的事情。

    公司倾向于将他们的系统的大量配置数据存储在数据库中,我不知道为什么,我认为这些决策中没有考虑太多。在OSS的世界里,我看不到这种事情经常发生。即使是需要大量配置的大型OSS程序,如Apache,也不需要连接到包含Apache_config表的数据库即可工作。在应用程序中处理大量的配置是一种糟糕的代码味道,将这些数据存储在数据库中只会导致更多的问题(如该线程所示)。