2

我正在使用具有各种不同实体的数据库表。这意味着我不能在其中包含任意数量的字段来保存各种不同的实体。相反,我只想保存最重要的字段(日期、参考 ID - 各种其他表的外键类型、最重要的文本字段等)和一个附加的文本字段,我想在其中存储更完整的对象数据。

最明显的解决方案是使用XML字符串并存储它们。第二个最明显的选择是JSON,通常更短,并且序列化/反序列化可能也更快......而且可能也更快。但真的是这样吗?我的对象也不需要严格序列化,因为 JsonSerializer 通常能够序列化任何东西。即使是匿名对象,也可以在这里使用。

解决这个问题的最佳解决方案是什么?

附加信息

我的数据库是高度规范化的,我正在使用实体框架,但为了拥有外部超快速全文搜索功能,我牺牲了一点数据库非规范化。只是为了我在 MySql 上使用 SphinxSE 的信息。Sphinx 将返回行 ID,我将使用这些行 ID 快速查询我的索引优化综合表,以便从中获取最重要的数据,这比在我的数据库中查询多个表要快得多。

我的表将有如下列:

  • RowID(自动递增)
  • EntityID(实际实体 - 但不直接相关,因为这必须指向不同的表)
  • EntityType(所以如果需要,我将能够获得实际的实体)
  • DateAdded(记录添加到此表时的时间戳)
  • Title
  • Metadata(与特定实体类型相关的序列化数据)

该表将使用 SPHINX 索引器进行索引。当我使用这个索引器搜索数据时,我会提供一系列EntityIDs和一个限制日期。索引器必须返回一个非常有限的分页数量的RowIDsDateAdded(降序)排序。然后我会将这些RowIDs加入我的表格并获得相关结果。所以这实际上不是全文搜索,而是过滤搜索。以这种方式获取RowIDs将非常快,并且从表中获取结果将比比较EntityIDsDateAdded比较快得多,即使它们会被正确索引。

4

4 回答 4

3

将数据保存在 SQL 数据库中且不会导致长期痛苦的唯一方法是实际创建一个适当的、规范化的索引模式,并在向域对象添加新属性时根据需要扩展该模式。

请不要尝试将对象“序列化”到 SQL 数据库。如果这确实是您想要做的,您最好使用对象数据库,例如db4o


更新:

根据评论和问题更新,这就是我目前对问题空间的理解:

  • 表结构已经规范化;
  • 全文引擎 (Sphinx) 被用于优化某些搜索;
  • 此处讨论的特定“序列化”数据将用作单个搜索结果的摘要或预览,并不代表完整的对象数据。

我对此的选择,按优先顺序,将是:

  • 使用 FTS 引擎的功能。
    几乎每个 FTS 引擎,包括 Sphinx,都允许将自定义属性存储为每个“文档”的一部分。目前您说您只存储行 ID,以便您可以加入此表。如果您根本不加入,您的结果会更快地返回,而是将此信息保留在全文索引本身中。您可以在此处输入的内容有一些非常严格的限制,但如果您可以解决限制,这是您的最佳选择。

  • 面向文档的数据库。
    您说您甚至没有真正使用 Sphinx 的“全文”部分,您只是在使用它来优化某些查询。那为什么不砍掉中间人呢?您建议将 JSON 作为序列化格式;MongoDB(仅举一个选项)原生支持BSON 。您仍然可以在公共列上创建索引,但与 mysql 不同的是,它实际上理解BSON 格式,并且能够比关系数据库中的 JSON 或 XML 字符串更有效地存储该数据。如果您仍然要进行非规范化,您可以自由选择您想要的任何存储库;选择最适合您的特定要求的产品。

  • 单表继承。
    这是一种常见的设计,它牺牲了标准化以换取映射的简单性。在你的情况下,整个目标是非规范化,所以这是一个很好的交易。如果有数百列,这不是一个好的选择,但是对于 10 或 20 列,这会很好,它将您的数据保留为“数据”,并且不会以任何显着方式影响性能。

  • XML 列。
    这种方法的优点是数据不是不透明的。它在数据库的上下文中实际上是有意义的。如果您必须将此信息存储mysql 数据库中 - 大概您希望运行一些临时查询 - 那么您最好将其存储为 mysql 可以实际理解的格式。另一方面,如果你 100% 肯定你永远不需要“反序列化”这些数据,直到它到达你的应用程序,那么我可能会选择......

  • 自定义二进制序列化格式。
    如果您必须将数据存储在 mysql 数据库中,并且您确定永远不需要索引它,甚至不需要从查询中读取它的内容,那么不要将宝贵的 I/O 浪费在臃肿的文本编码上。与二进制相比,即使是 JSON 也是臃肿的,因为 JSON 必须存储所有属性名称;如果您自己进行序列化,则可以使用一两个字节来确定类型,然后以已知顺序反序列化剩余的字段/属性。只有数据,没有元数据。

    我什至不会在BinaryFormatter这里使用 .NET,我会创建自己的高度优化版本。毕竟,这需要快快快!进入表的每个额外字节都会使查询变慢。您甚至可以 GZip 压缩某些数据,具体取决于其中的内容。


除非我还没有完全理解您的要求,否则我什至不会考虑任何其他选择。

于 2010-04-14T15:25:22.857 回答
1

不要这样做。这是个坏主意。

如果你真的必须这样做,我会使用 XML。例如,只要字段是 XML 类型,SQL Server 就允许您针对 XMl 进行查询。

从某种意义上说,您正在做面向对象数据库所做的事情。它们已经失宠,因为在大多数情况下,ORM 工具(如 Hibernate 和 Microsoft 的实体框架)允许您同时拥有 OO 和关系世界的精华。

于 2010-04-14T15:22:26.200 回答
0

你看过 NoSql 数据库吗?

http://nosql-database.org/

否则,我不得不说您的数据模型将来可能会导致您陷入困境......

于 2010-04-14T15:20:33.520 回答
0

实际上,我一直在我的 RDBMS 中使用文本 blob。当用于正确的目的时,它可以对性能产生积极影响,并节省许多表的存在和维护以及开发时间。当您需要存储有关行的频繁更改的非关系元数据时,它是理想的选择。

虽然我只会考虑将文本 blob 用于 KVO 对象(即非实体 - 仅对其所保留的行有意义的对象)。如果您需要对其进行任何服务器端操作(即查询等),也不要打扰。

For those that are interested I've developed a fast, resilient Type Serializer that is ideal for storing text-blobs in a compact, human-readable text-format.

于 2010-08-18T22:46:38.417 回答