2010-10-08 119 views
0

我有三个表:动作,消息,喜欢。它定义了继承,消息和喜欢是动作的孩子(专业化)。SQL泛化/专业化,数据冗余

消息和Like都有列userId和createdAt。这些应该当然移动到parrent表Action并从Message和Likes中移除。但只有一种情况是我需要从数据库中选择消息和喜好,而在其他情况下,我只选择其中的一种消息或喜好。

可以在child和parrent表中复制userId和createdAt吗?它花费磁盘空间,但保存一个连接 - 我将不得不加入消息,每次需要userId和createdAt时都要使用动作。还有什么我需要改变我现在的代码...

你会建议什么?

回答

2

在我看来,这是一个过早优化的案例(或者如果您愿意的话,可以提前非规范化)。你是猜测连接开销会导致重大问题,所以你猜测重复依赖表中的userId和createdAt列将显着提高性能。

我建议你不要重复列,直到你知道有一个真正的问题。我对墙上的性能优化提出了一些观察,以提醒自己我应该在类似情况下做些什么:

  1. 它没有坏,直到它坏了。
  2. 你不能改善你没有衡量的东西。
  3. 程序在最糟糕的地方花费了惊人的时间。
  4. 让它运行。让它正确运行。让它快速运行。
    • 优化实际上是你应该做的最后一件事。
    • 做事快错误没有太大好处。

而且在非规范化几点意见:

  1. 你不能非规范化说这是不归。
  2. 大多数开发者如果从屏幕后面跳出来,就会像第一个女妖一样尖叫,然后在他们头上打出一个棒球棒。
  3. 非规范化被认为是解决数据库性能问题的灵丹妙药。问题是,那些推荐非规范化的人往往从未标准化任何事情。
  4. “出于性能原因而非规范化”是一个拙劣的借口,“做我们一直以来做的事”的想法,特别是当设计中包含非规范化时。

以我的经验,我无法确定在编写代码之前会出现性能问题。问题总是出现在我永远不会想到的地方。因此,我发现我的最佳选择是始终写出最简单,最清晰的代码,并尽可能简单地设计数据库,遵循规范化规则,尽我所能,然后处理出现了。可能仍然存在需要注意的性能问题(但是,令人惊讶的是,并不是所有这些都经常发生),但最终我会得到简单,清晰且易于理解/维护的代码,它们运行在一个简单的,精心设计的数据库。

分享和享受。

+0

谢谢,伟大的职位。 Basicaly,我应该摆脱重复并重写遗留代码? :-) – PetrB 2010-10-08 11:48:04

+0

@PetrB:谢谢。如果涉及遗留代码,则显然是不同的情况,并且您可能无法(由于时间限制或组织限制)重写所有内容。我的意见是针对新的数据库和代码。 – 2010-10-08 11:53:04

+0

这是我的个人项目,所以时间或其他任何东西都不重要,相关的遗留代码也不是一个大问题。从你的帖子中可以明显看出,即使我只需要一个孩子,最好在所有情况下都通过加入父表来获取数据。 – PetrB 2010-10-08 11:59:09