【问题标题】:What is the best way to store and search through object transactions?存储和搜索对象事务的最佳方式是什么?
【发布时间】:2008-11-06 14:43:12
【问题描述】:

我们有一个大小合适的面向对象应用程序。每当应用程序中的对象发生更改时,对象更改都会保存回数据库。然而,这已经变得不太理想了。

目前,交易被存储为一个交易和一组交易LI。

事务表包含 who、what、when、why、foreignKey 和 foreignTable 字段。前四个是不言自明的。 ForeignKey 和 foreignTable 用于确定哪个对象发生了变化。

TransactionLI 具有时间戳、密钥、val、oldVal 和 transactionID。这基本上是一个 key/value/oldValue 存储系统。

问题是这两个表用于应用程序中的每个对象,所以它们现在是相当大的表。将它们用于任何事情都很慢。索引只能起到这么大的作用。

所以我们正在考虑其他方法来做这样的事情。到目前为止我们考虑过的事情: - 按时间戳之类的方式对这些表进行分片。 - 对两张表进行非规范化并将它们合并为一张。 - 以上两者的结合。 - 在更改后序列化每个对象并将其存储在颠覆中。 - 可能是别的什么,但我现在想不起来。

整个问题是我们希望有一些机制来正确存储和搜索交易数据。是的,您可以强制将其输入到关系数据库中,但实际上,它是事务数据,应该相应地存储。

其他人都在做什么?

【问题讨论】:

  • 您使用的是什么数据库?您可能想研究 SQL 2008 中的 SQL 更改跟踪。它不会跟踪您的对象,但会跟踪您的数据更改并对其进行版本化。

标签: search transactions oop storage


【解决方案1】:

我们采取了以下方法:-

  1. 所有对象都被序列化(使用标准的 XMLSeriliser),但是我们用序列化属性修饰了我们的类,这样生成的 XML 就小得多(例如,将元素存储为属性并在字段名称上删除元音)。如有必要,可以通过压缩 XML 来更进一步。

  2. 通过 SQL 视图访问对象存储库。该视图前面有许多结构相同但表名附加了 GUID 的表。当前一个表达到临界质量(预定的行数)时,会生成一个新表

  3. 我们每晚运行一个归档例程,生成新表并相应地修改视图,以便调用应用程序看不到任何差异。

  4. 最后,作为通宵例行程序的一部分,我们将不再需要磁盘(然后是磁带)的所有旧对象实例存档。

【讨论】:

    【解决方案2】:

    我从来没有为这类问题找到完美的解决方案。您可以尝试的一些事情是您的数据库是否支持分区(或者即使它不支持您自己也可以实现相同的概念),但是按对象类型对该日志表进行分区,然后您可以按日期/时间或您的进一步分区对象 ID(如果您的 ID 是数字,则可以很好地工作,不确定 guid 将如何分区)。

    这将有助于保持表的大小,并将所有相关事务保存到对象的单个实例中。

    您可以探索的一个想法是,您可以将数据存储为 blob(文本或二进制),而不是将每个字段存储在名称值对表中。例如,将对象序列化为 Xml 并将其存储在字段中。

    这样做的缺点是,当您的对象发生变化时,您必须考虑这将如何影响所有历史数据,如果您使用 Xml,那么有一些简单的方法可以更新历史 xml 结构,如果您使用二进制有一些方法,但您必须更加意识到自己的努力。

    我在存储一个相当复杂的对象模型方面取得了巨大的成功,该模型具有大量的相互关系作为 blob(.net 中的 xml 序列化程序没有处理对象之间的关系)。我可以很容易地看到自己存储二进制数据。将其存储为二进制数据的一个巨大缺点是,如果您使用现代数据库(如 MSSQL)可以访问数据,则必须使用 Xml 将其从数据库中取出。

    最后一种方法是拆分这两种模式,您可以定义一个差异模式(我假设一次更改不止一个属性),例如想象存储这个 xml:

    <objectDiff>
    <field name="firstName" newValue="Josh" oldValue="joshua"/>
    <field name="lastName" newValue="Box" oldValue="boxer"/>
    </objectDiff>
    

    这将有助于减少行数,如果您使用 MSSQL,您可以定义 XML Schema 并获得一些围绕对象的丰富查询能力。您仍然可以对表进行分区。

    乔什

    【讨论】:

      【解决方案3】:

      根据您的特定应用程序的特性,另一种方法是将实体本身的修订保留在其各自的表中,以及每个修订的人员、内容、原因和时间。 who、what 和 when 仍然可以是外键。

      虽然我会非常小心地使用这种方法,因为这仅适用于每个实体/实体类型的更改量相对较小的应用程序。

      【讨论】:

        【解决方案4】:

        如果查询数据很重要,如果您拥有 SQL Server 企业版,我会在 SQL Server 2005 及更高版本中使用真正的分区。我们有数百万行按年分区到当月的每一天 - 您可以根据应用程序的需求进行精细化,最多可使用 1000 个分区。

        或者,如果您使用的是 SQL 2008,您可以查看过滤索引。

        这些解决方案可让您保留现有的简化结构,同时提供查询该数据所需的性能。

        显然应该考虑拆分/归档旧的更改。

        【讨论】:

          猜你喜欢
          • 2014-06-29
          • 2010-10-17
          • 2017-01-14
          • 2021-04-24
          • 2010-12-14
          • 1970-01-01
          • 1970-01-01
          • 2011-04-15
          • 2017-01-29
          相关资源
          最近更新 更多