15

我正处于开发数据库驱动系统的早期阶段,系统的最大部分围绕继承类型的关系展开。有一个包含大约 10 列的父实体,并且将有大约 10 个从父实体继承的子实体。每个子实体将有大约 10 列。我认为给父实体提供自己的表并给每个子实体自己的表是有意义的 - 每个子类的表结构。

今天,我的用户要求查看我创建的系统的结构。他们对每个子类的表结构的想法犹豫不决。他们更喜欢一个大约 100 列的大表,因为他们更容易执行自己的自定义查询。

为了用户,我应该考虑对数据库进行非规范化吗?

4

13 回答 13

59

绝对不。您以后可以随时创建一个视图,向他们展示他们想要看到的内容。

于 2009-11-13T16:29:27.297 回答
13

他们实际上是在要求报告。

您可以让他们访问包含他们需要的所有字段的视图......这样您就不会弄乱您的数据模型。

于 2009-11-13T16:29:30.980 回答
8

不。正确地构造数据,如果用户需要数据的非规范化视图,请将其创建为数据库中的视图。

或者,考虑到 RDBMS 可能不是该项目的合适存储工具。

于 2009-11-13T16:30:15.917 回答
5

出于某种原因,他们是系统的用户而不是程序员。为他们的查询提供单独的界面。像这样的高级用户既可以提供帮助,也可以让人很痛苦。只需说明您需要以某种方式设计数据库,这样您就可以完成您的工作。一旦完成,您就可以提供其他方法来简化查询。

于 2009-11-13T16:35:17.787 回答
4

他们知道什么!?您可能会争辩说,用户甚至不应该首先直接访问数据库。

这样做会让您面临巨大的性能问题,仅仅因为几个用户正在运行荒谬的查询。

于 2009-11-13T16:35:44.160 回答
3

如果您以用户想要的格式创建 VIEW,同时仍保持正确的规范化表,怎么样?

于 2009-11-13T16:29:55.327 回答
3

除了支持或反对用户提议的许多技术原因之外,您需要在同一页面上传达各种场景的后果以及(更重要的是)这些后果的成本。如果用户是你的客户并且他们付钱给你做一份工作,解释他们糟糕的“提议”想法可能会花费他们更多的开发时间、额外的硬件资源等。

希望你能以这样一种方式来解释它,以展示你的专业知识,以及为什么你的想法从长远来看对你的用户来说更有价值。

于 2009-11-13T16:58:04.847 回答
2

正如每个人或多或少提到的那样,这种方式很疯狂,你总是可以建立一个视图。

如果您无法让他们在这一点上出现,请考虑向他们展示此线程以及权衡说用户正在干预他们不完全理解的事情的专业人士的数量,其影响将是被破坏的基础。

开发人员工艺的很大一部分是对无法长期发挥作用的感觉,并且规范化规则在这方面几乎是规范的。在某些情况下,您需要进行非规范化(数据仓库等),但这听起来不像是其中之一!

听起来你手上可能有一个特别令人不安的用户品牌——那些认为只要有时间,他们自己就能更好地完成你的工作的业余开发者。这可能有帮助,也可能没有帮助,但我发现这些类型的人对展示的反应很好——现在有几次我发现,如果我穿着得体并且在我的个性中表现出一点力量,这会让他们感觉像我是专家,可以在问题开始之前防止一堆问题。

于 2009-11-13T18:03:18.273 回答
1

我强烈建议提出一个不涉及对您的数据库运行直接报告的人的答案。发生这种情况的那一刻,您的数据库结构就一成不变,您基本上可以将其视为遗产。

视图是一个好的开始,但稍后您可能希望将其构建为导出,以进一步解耦。当然,然后你会遇到想要“实时”数据的人。适当的业务分析通常表明这是不必要的。实际的实时需求不能通过报告系统得到最好的处理。

只是要明确一点:我个人倾向于按子类方法使用表,但我认为这实际上并不像直接报告事务表那样大。

于 2009-11-13T16:50:20.510 回答
1

我会选择视图(正如其他人所建议的那样)或内联表值函数(这样做的好处是您需要参数 - 例如日期范围或客户帐户 - 这可以帮助阻止用户在没有任何限制的情况下进行查询问题空间)首先。内联 TVF 实际上是一个参数化视图,就引擎如何处理它们而言,它更接近于视图,而不是多语句表值函数或标量函数,后者的性能非常差。

但是,在某些情况下,如果视图复杂或密集,这可能会影响生产性能。对于编写不佳的临时用户查询,与构建更好的查询相比,它还可能导致锁定持续时间更长或升级程度更高。在存在多对一或多对多关系的情况下,用户也可能会误解 ER 数据模型并产生乘数。下一个选项可能是用索引实现这些视图或制作表格并保持更新,这让我们更接近我的下一个选项......

因此,鉴于视图选项的这些缺点,并且已经考虑通过开始制作数据副本来缓解它,我会考虑的下一个选项是拥有一个单独的只读(对于这些用户)版本的数据,其结构不同. 通常,我会首先查看 Kimball 风格的星型模式。您不需要拥有成熟的时间一致的数据仓库。当然,这是一种选择,但您可以简单地使报告模型与数据保持同步。星型模式是一种特殊的非规范化形式,特别适合数值报告,并且给定的星型不应被用户意外滥用。您可以通过多种方式使星标保持最新状态,包括触发器、计划作业等。

尽管这样的解决方案可能需要您有效地将存储需求增加一倍以上,但与其他实践相比,如果您很好地了解您的数据并且不介意拥有两个模型(一个用于事务,一个用于分析),它可能是一个非常好的选择(请注意,无论如何,使用最简单的第一个视图选项,您已经开始进行这种逻辑分离)。

一些架构师通常会将他们的服务器加倍,并使用具有某种复制的 SAME 模型,以提供索引更重或不同的报告服务器。这样的第二台服务器不会影响具有报告要求的生产事务,并且可以很容易地保持最新状态。只有一个模型,但是当然,这也存在同样的可用性问题,即只允许用户临时访问底层模型,而不会影响性能,因为他们有自己的游乐场。

有很多方法可以给这些猫剥皮。祝你好运。

于 2009-11-13T18:23:40.313 回答
1

顾客永远是对的。但是,当您将他们的要求转换为美元和美分时,客户可能会退缩。一个 100 列的表将需要额外的开发时间来编写代码来执行数据库通过正确实现自动执行的操作。此外,他们的支持成本会更高,因为更多的代码意味着更多的问题和更难调试。

于 2009-11-13T18:28:25.383 回答
1

我将在这里扮演魔鬼的拥护者,并说这两种解决方案听起来都像是对实际数据的不良近似。面向对象的编程语言不倾向于使用这些数据模型中的任何一个来实现是有原因的,这并不是因为 Codd 1970 年关于关系的想法是存储和查询面向对象数据结构的理想系统。:-)

请记住,SQL 最初被设计为一种用户界面语言(这就是为什么它看起来有点像英语,而不像那个时代的其他语言:Algol、C、APL、Prolog)。我听说今天不向用户公开 SQL 数据库的唯一原因是安全性(他们可能会关闭服务器!)和可用性(当您可以点击时,谁愿意编写 SQL?),但如果是他们的服务器和他们想,那为什么不让他们呢?

鉴于“系统的最大部分围绕继承类型的关系”,那么我会认真考虑一个数据库,让我可以原生地表示它,要么是Postgres(如果 SQL 很重要),要么是原生对象数据库(很棒可以使用,如果您不需要 SQL 兼容性)。

最后,请记住,每个工程决策都是一种权衡。通过“坚持你的枪”(正如其他人所提议的那样),你隐含地说用户的欲望价值为零。不要向 SO 索要正确答案,因为我们不知道您的用户想要对您的数据做什么(甚至您的数据是什么,或者您的用户是谁)。去告诉他们为什么你想要一个多表解决方案,然后与他们一起制定一个你们都可以接受的解决方案。

于 2009-11-13T18:30:25.520 回答
0

您已经实现了Class Table Inheritance并且他们要求Single Table Inheritance。这两种设计在某些情况下都是有效的。

您可能想要一份 Martin Fowler 的企业应用程序架构模式的副本,以详细了解每种设计的优缺点。无论如何,那本书是你书架上的经典参考书。

于 2011-07-12T16:51:00.217 回答