3

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

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

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

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

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

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

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

其他人都在做什么?

4

4 回答 4

1

我们采取了以下方法:-

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

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

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

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

于 2008-12-12T19:13:23.140 回答
0

我从来没有为这类问题找到一个很好的解决方案。您可以尝试的一些事情是您的数据库是否支持分区(或者即使它不支持您自己也可以实现相同的概念),但是按对象类型对此日志表进行分区,然后您可以按日期/时间或您的进一步分区对象 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 模式并获得一些围绕对象的丰富查询能力。您仍然可以对表进行分区。

乔什

于 2008-11-06T15:04:54.343 回答
0

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

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

于 2008-11-06T15:47:12.493 回答
0

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

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

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

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

于 2008-12-05T10:37:29.907 回答