Mysql 数据库规范化-我想?

Mysql 数据库规范化-我想?,mysql,jakarta-ee,normalization,Mysql,Jakarta Ee,Normalization,我们有一个J2EE内容管理和电子商务系统,在这个系统中——为了一个简单的例子——假设我们有100个对象。所有这些对象都扩展了相同的基类,并且都共享许多相同的字段 让我们以两个对象为例:一个发布在网站上的新闻项目和一个在网站上销售的产品。这两者都具有共同的属性: id:id、客户端id、父id(长) 标志:已删除、已存档、不活动(布尔值) 日期:创建、修改、删除(日期时间) 内容:名称、描述 当然,它们有一些不同的特性: 新闻项目:作者、发布日期 产品:价格、税金 所以(最后)这是我的问题

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

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

  • id:id、客户端id、父id(长)
  • 标志:已删除、已存档、不活动(布尔值)
  • 日期:创建、修改、删除(日期时间)
  • 内容:名称、描述
当然,它们有一些不同的特性:

  • 新闻项目:作者、发布日期
  • 产品:价格、税金
所以(最后)这是我的问题。假设我们的系统中有100个对象,它们都遵循这个模式。它们有许多重叠的字段,还有一些独特的字段。就关系数据库而言,我们最好使用:

选项一:少表,普通表

  • 表id:id、客户端id、父id(长)(id是主键,是所有对象的GUID)
  • 表_标志:id、已删除、已存档、非活动(布尔值)
  • 表_日期:id、创建、修改、删除(日期时间)
  • 表_内容:id、名称、说明
  • 表_新闻:id、作者、发布日期
  • 表_产品:标识、价格、税
选项二:更多表格,公共字段重复

  • 表_新闻:id、客户id、父id、已删除、已存档、不活动、名称、描述、作者、发布日期
  • 表_产品:id、客户id、父id、已删除、已存档、不活动、名称、说明、价格、税费
我是一名开发人员,而不是DBA,因此我更喜欢选项一。但是还有一个队员更喜欢第二种选择,我认为他的观点是正确的

选择一:利弊

  • Pro:将公共字段封装到公共表中
  • 赞成:需要更改公共字段吗?在一个地方换
  • Pro:仅在需要时创建新字段/表
  • 优点:更容易动态创建查询,重复代码更少
  • 缺点:更多的连接来创建对象(不确定DB是否会对其产生影响)
  • 缺点:存储对象的查询更复杂(不确定DB是否会对其产生影响)
  • 缺点:随着时间的推移,普通表格将变得巨大
选择二:利弊

  • 赞成者:也许最好在表之间分配所有对象的负载
  • Pro:可以在客户端ID上索引新闻表,并在父ID上索引产品表
  • 优点:更易于人眼阅读:易于在一个表中查看对象的所有字段
我的两分钱

对我来说,我更喜欢第一种选择的优雅——但可能是我试图在关系数据库上强制使用面向对象模式。如果所有条件都相同,我会选择选项一,除非DB专家告诉我,当系统中有数百万个对象时,选项一会产生性能问题

为这个冗长的问题道歉。我对DB行话不太在行,所以如果我能更好地理解规范化之类的术语,我可能会更简洁地总结这一点。我试图搜索关于这个主题的答案,虽然我找到了很多接近的答案(我怀疑这是一个常见的DB问题),但我找不到任何答案来回答我所有的问题。我通读了关于标准化的内容:

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

谢谢

约翰

你应该读马丁·福勒的作品。他为您描述的场景写了几个选项:

  • :一个用于所有对象子类型的表。存储所有属性,在不适用于行的对象子类型的位置将其设置为NULL

  • :一个表用于所有子类型共有的列,然后每个子类型一个表用于存储子类型特定的列

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

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

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

但是,请注意,我使用了上面的单词subtype。只有当不同的对象类型是公共基类的子类型时,我才会使用这些设计。我假设
新闻项目
产品
实际上不共享逻辑基类(除了
对象
);它们不是普通超类的子类型


所以为了OO设计,我会选择具体的表继承。这避免了这些子类型之间的任何不适当耦合。这两个表有相同的列,但它们基本上相当于簿记,与类的功能无关,因此与表无关

嗨,比尔,我的问题一定写得比我想象的好一点,因为你的答案正是我想要的。你是对的——事实上,我的例子中的继承链看起来更像:*SuperObject*ContentObject扩展SuperObject*NewsItem扩展ContentObject*BuyableObject扩展SuperObject*ProductObject扩展BuyableObject这就是要点。因此,我会让所有对象都有公共字段的表,然后是ContentObjects有公共字段的表,如果有必要的话,还有NewsItem有公共字段的表。但是我的后续问题是,将