如何在关系数据库中存储值对象?

时间:2013-03-27 02:22:32

标签: serialization relational-database value-objects

我正在处理一个包含许多表示简单(非相关)值的对象的大型项目。有时这些值是单个字符串,有时它们是两个字符串,有时是字符串和int ...

目前,我们的关系数据库中有一个“值”表,其中包含以下列:IdCategoryString1String2 ...,{{1 }},Int1 ...,Int2等。这很方便,但很乱。

这些值都具有以下属性:

  • 具有相同Double1的每个对象具有相同的属性(即输入)。
  • 没有对象相关(唯一的键是Category主键)。

我们如何摆脱这个烂摊子?我认为,我们的选择如下:

  1. 只需根据需要添加列,忘记表和对象之间的语义映射。把它堆起来。
  2. 为每个值对象创建一个新表。这将向数据库添加大量表,其中大多数表将少于6行。我担心所有这些额外的表都会添加到数据库中的噪音。
  3. 仅针对这些对象部署无架构数据库(在我们的部署方案中不太可能)。
  4. 创建一个包含IdId列和BLOB Category列的表,并将值对象序列化到值列中。这可行吗?
  5. This post重申了我们的选择。使用序列化有任何警告或陷阱吗?有没有我不知道的选择?建议最受欢迎。

1 个答案:

答案 0 :(得分:2)

我从another relevant question导航,偶然发现了这一点。虽然它已经很老了,但我很有兴趣回答,因为它不仅提出了一个非常明确的问题,而且还允许人们对数据库非规范化作为一个整体进行论证。

对于数据库进行非规范化,有很多原因甚至更多借口。性能可能是最重要的,但数据分类的难度(例如手头的问题)绝对是最常见的。此外,有很多种方式数据库可以非规范化,并且OP可以解决大量的数据库问题。

事实上,数据库应该被归一化为万不得已,其他一切都失败后。原因包括:

  • 数据对人类和RDBMS都毫无意义。有些人很难理解甚至记住名为Integer1的字段或可能存有任何东西的序列化值的目的。并且RDBMS无法从序列化实体中提取值,以便对结果进行排序或应用聚合。

  • 难以维护易失性架构。数据库模式应该是常量的原因。其他更高级别取决于它。如果模式在一夜之间发生变化,应用程序也应该更改,以反映新状态。更糟糕的是,视图,存储过程和其他依赖数据库组件变得同样难以维护。

  • 无法强制执行约束,无法创建索引。将序列化字段定义为外键没有意义,或者将其限制为一组特定的值。这取消了大量数据库的自我保护机制。数据完整性越低意味着管理成本越高此外,索引在这里同样没用,使得表格不易于优化。

  • 元数据最终必须存储为数据。想象一下多语言CMS,其中有一个主article表来存放文章。现在,对于支持的每种语言,都有相应的article_{lang}表来保存翻译(即article_enarticle_frarticle_es等。为了记录文章的现有翻译,应创建“关系”表,其中包含article表的外键,语言ID,转换表的表名以及应该是的字段。 FK到转换表但不能定义为一个。然后,尝试编写一个查询,计算每篇文章的可用翻译!

尽可能避免非规范化。如果实体可以被分类到一定程度,那么IS-A relations可能就是答案。为了支持任意属性,或者当分类不值得时,a key/value pair table,使用包含规范化数据的表的外键,就足以成为牺牲品。