1

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

目前,我们的关系数据库中有一个“值”表,其中包含以下列:IdCategoryString1String2...、Int1Int2...Double1等。它很方便,但很乱。

这些值都具有以下属性:

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

我们如何摆脱这种混乱局面?在我看来,我们的选择如下:

  1. 只需根据需要继续添加列,并忘记表和对象之间的语义映射。把它堆起来。
  2. 为每个值对象创建一个新表。这将向数据库中添加大量表,其中大多数表少于 6 行。我担心所有这些额外的表都会添加到数据库中。
  3. 仅为这些对象部署一个无模式的数据库(在我们的部署方案中实际上不可能)。
  4. 创建一个带有IdCategory列和 BLOBValue列的表,并将值对象序列化到值列中。这可行吗?

这篇文章重申了我们的选择。使用序列化是否有任何警告或陷阱?有没有我不知道的选项?欢迎咨询。

4

1 回答 1

2

我从另一个相关问题导航时偶然发现了这一点。虽然它已经很老了,但我很想回答,因为它不仅提出了一个很好的问题,而且还允许人们对整个数据库非规范化进行争论。

数据库被非规范化有很多原因,甚至更多的借口。性能可能是最重要的,但数据分类的困难(例如手头的问题)绝对是最常见的。此外,可以通过多种方式对数据库进行非规范化,其中很多都由 OP 解决。

但事实是,在其他一切都失败后,数据库应该作为最后的手段进行非规范化。其原因包括:

  • 数据对人类和 RDBMS 都变得毫无意义。有人很难理解,甚至很难记住一个命名字段Integer1或可能包含任何内容的序列化值的用途。并且 RDBMS 无法从序列化实体中提取值以对结果进行排序或应用聚合。

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

  • 无法强制执行约束,无法创建索引。将序列化字段定义为外键或将其限制为一组特定的值是没有意义的。这取消了很多数据库的自我保护机制。更少的数据完整性意味着更多的管理成本。此外,索引在这里同样没用,使表对优化的开放性降低。

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

所以尽可能避免非规范化。如果实体可以在一定程度上进行分类,那么IS-A 关系可能就是答案。为了支持任意属性,或者当分类不值得时,一个键/值对表,具有表的外键来保存规范化数据,这已经足够牺牲了。

于 2013-10-29T17:44:39.387 回答