2012-01-23 49 views
1

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

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

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

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

  • 新闻资料:作者,过帐日期
  • 产品:价格,税收

所以,(最终)这里是我的问题。假设我们的系统中有100个对象,并且它们都遵循这种模式。他们有许多重叠的领域,以及一些独特的领域。在关系数据库中的条款,我们会过得更好用:

方案一:少表,普通表

  • 的table_id:ID,客户端ID,父ID(长)(id是主键,对于所有对象GUID)
  • table_flag:ID,删除,存档,无效(布尔值)
  • table_date:ID,创建,修改,删除(日期时间)
  • table_content:ID,名称,描述
  • table_news:身份证,作者,发布日期
  • table_product:ID,价格,税收

方案二:其他表,通用字段重复

  • table_news:身份证,委托人身份证,家长ID,已删除,存档,不活动,名称,描述,作者,发帖日期
  • table_product:id,客户端ID,父ID,已删除,存档,无效,名称,描述,价格,税收

为了充分披露 - 我是开发人员而不是DBA,因此我更喜欢选项一。但还有另外一名队员喜欢选项二,我认为他提出了有效的观点。

方案一:优点和缺点

  • 专业:普通封装领域为普通表。
  • 临:需要改变一个共同的领域?在一个地方改变它。
  • 专业版:仅在需要时才创建新的字段/表。
  • 临:更动态地创建查询,少重复的代码
  • 缺点:更多加入到创建对象(不知道的对DB的影响)
  • 缺点:更复杂的查询来存储对象(不知道DB的对影响)
  • 缺点:普通表将成为巨大的随着时间的推移

方案二:优点和缺点

  • Pro:或许最好是将所有对象的负载分配到表中?
  • 专业:可以索引客户端ID上的新闻表,并索引产品表上的父ID。
  • Pro:人眼更易读:易于查看某个表格中某个对象的所有字段。

我的两分钱

对于我来说,我更喜欢第一种选择的风采 - 但也许那就是我试图迫使一个关系型数据库的面向对象的模式。如果所有的东西都是平等的,我会选择第一种方法,除非数据库专家告诉我,当系统中有数百万个对象时,选项一会导致性能问题。

道歉的长期啰嗦的问题。我对数据库术语并不擅长,所以如果我能更好地理解正常化这样的术语,我可能会更简洁地总结一下。我试图搜索这个主题的答案,虽然我发现很多很接近(我怀疑这是一个常见的数据库问题),但我找不到任何回答我所有问题的答案。我通过this article阅读规范化:

但我并没有完全理解它。一方面它说你应该删除任何冗余。但另一方面,它是说每个属性只应该定义一个对象。

感谢,

约翰

回答

2

应该由Martin Fowler阅读Patterns of Enterprise Application Architecture。他写道:关于你所描述的情景几个选项:

  • Single Table Inheritance:所有的对象亚型一张桌子。存储所有属性,如果它们不适用于行的对象子类型,则将它们设置为NULL。

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

  • Concrete Table Inheritance:每个子类型的一个表,存储所有子类型通用的子类型专用列和列。

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

这些设计中的每一个都有优点和缺点,因此根据最常见的访问数据方式选择一种解决方案。

但是,请注意我上面使用这个词的子类型。只有当不同的对象类型是共同基类的子类型时,我才会使用这些设计。我假设News itemProduct实际上并不共享逻辑基类(除了Object);它们不是共同超类的子类型。因此,为了OO设计,我会选择混凝土表继承。这避免了这些亚型之间的任何不适当的耦合。这两个表格有两个共同的列,但它们基本上相当于簿记,而不是与班级的功能以及表格有关。

+0

嗨比尔,我一定写了我的问题比我想象的要好一些,因为你的回答正是我寻找的东西。而你是正确的 - 事实上,我的例子继承链看起来更象这样: *超对象 * ContentObject扩展超对象 * NewsItem延伸ContentObject * BuyableObject扩展超对象 * ProductObject延伸BuyableObject 这是要点。因此,我将拥有包含所有对象通用字段的表格,然后为ContentObjects公用的字段表格,然后在必要时为NewsItem字段创建表格。 –

+0

但是我的后续问题是 - 将常见表中的所有常见信息都打出来会有什么性能影响? –

+0

不可以。不管怎样,您都必须为每个新闻/产品行存储它,因此您最终会得到相同数量的行。如果有的话,当您需要产品或新闻项目的所有属性时,它可以帮助您减少JOINing表的需求。 –