数据库规范化 - 我想?

时间:2012-01-23 17:09:13

标签: mysql java-ee normalization

我们有一个J2EE内容管理和电子商务系统,在这个系统中 - 为了一个简单的例子 - 假设我们有100个对象。所有这些对象都扩展了相同的基类,并且它们共享许多相同的字段。

让我们以两个对象为例:一个将在网站上发布的新闻项目,以及一个将在网站上销售的产品。这两者都有共同的属性:

  • ID:id,客户端ID,父ID(长)
  • 标志:已删除,已存档,无效(布尔值)
  • 日期:已创建,已修改,已删除(日期时间)
  • 内容:姓名,描述

当然,他们有一些不同的属性:

  • 新闻项目:作者,发布日期
  • 产品:价格,税款

所以(最后)这是我的问题。假设我们的系统中有100个对象,它们都遵循这种模式。它们有许多重叠的字段,以及一些独特的字段。就关系数据库而言,我们会更好:

选项一:减少表格,通用表格

  • table_id:id,客户端ID,父ID(长)(id是主键,所有对象的GUID)
  • table_flag:id,deleted,archived,inactive(boolean)
  • table_date:id,created,modified,deleted(datetime)
  • table_content:id,name,description
  • table_news:id,作者,发布日期
  • table_product:id,price,tax

选项二:更多表格,重复的常用字段

  • table_news:id,客户ID,父ID,已删除,已存档,无效,姓名,说明,作者,发布日期
  • table_product:id,客户ID,父ID,已删除,已存档,无效,名称,说明,价格,税

对于完全披露 - 我是开发人员而不是DBA,因此我更喜欢选项。但是还有另一个团队成员更喜欢选项二,我认为他提出了有效的观点。

选项一:优点和缺点

  • Pro:将公共字段封装到公用表中。
  • 亲:需要改变一个共同领域?在一个地方更改它。
  • Pro:仅在需要时创建新的字段/表格。
  • Pro:更容易动态创建查询,重复性更低的代码
  • Con:更多加入创建对象(不确定数据库对此的影响)
  • Con:存储对象的更复杂查询(不确定数据库对此的影响)
  • Con:随着时间的推移,普通表会变得很大

选项二:优点和缺点

  • Pro:也许最好在表中分配所有对象的负载?
  • Pro:可以在客户端ID上索引新闻表,并在父ID上为产品表编制索引。
  • Pro:人眼更易读:在一个表格中轻松查看对象的所有字段。

我的两分钱

对我来说,我更喜欢第一种选择的优雅 - 但也许这就是我试图在关系数据库上强制面向对象的模式。如果所有事情都是平等的,我会选择一个,除非数据库专家告诉我,当我们在系统中有数百万个对象时,选项一会产生性能问题。

为冗长的问题道歉。我对DB lingo不太满意,所以如果我更好地理解像规范化这样的术语,我可能会更简洁地总结一下。我试图搜索关于这个主题的答案,虽然我发现很多很接近(我怀疑这是一个常见的数据库问题)但我找不到任何能回答我所有问题的答案。我通过this article了解了规范化:

但我并不完全明白。一方面,它说你应该删除任何冗余。但另一方面,它说每个属性应该只定义一个对象。

谢谢,

约翰

1 个答案:

答案 0 :(得分:2)

你应该阅读Martin Fowler撰写的Patterns of Enterprise Application Architecture。他为您描述的场景写了几个选项:

  • Single Table Inheritance:所有对象子类型的一个表。存储所有属性,将它们设置为NULL,使其不适用于行的对象子类型。

  • Class Table Inheritance:一个表格用于所有子类型共有的列,然后是每个子类型的一个表格,用于存储特定于子类型的列。

  • Concrete Table Inheritance:每个子类型一个表,存储所有子类型共有的特定于子类型的列和列。

  • Serialized LOB:所有对象子类型的一个表。将常用属性存储为常规列,但将可选或特定于子类的列组合为存储XML或JSON或您想要的任何格式的BLOB中的字段。

这些设计中的每一个都有利有弊,因此请根据您访问数据的最常用方式选择解决方案。

但是,请注意我使用上面的子类型一词。只有当不同的对象类型是公共基类的子类型时,我才会使用这些设计。我假设News itemProduct实际上并不共享逻辑基类(Object除外);它们不是普通超类的子类型。

因此,为了OO设计,我会选择Concrete Table Inheritance。这避免了这些子类型之间的任何不适当的耦合。这两个表有共同的列,但它们基本上等于簿记,而不是与类的功能有关,因此与表有关。