设计数据库的最简单,最有效的方法是什么?从我的角度来看,应用程序的数据存储设计有两个选项:在编写任何应用程序代码之前,请尽可能尽最大可能设计数据库。这为您提供了可以使用的基本数据结构的优点。我认为,这样做的缺点是您将对应用程序进行大量更改,因为这些更改会影响整个应用程序开发周期中数据的更改内容/位置/方式。

将数据库设计为该应用程序实现了。当您在编写应用程序时需要一些数据库对象时,可以与应用程序并行(按时间顺序)开发数据库。我所看到的好处是减少了对数据库结构的更改。缺点是应用程序代码和数据库开发之间的时间和开发工作的划分。

根据您的经验,您发现哪种方法是最有效和最有效的方法?

评论

使用SDLC分而治之

您可能会发现flywaydb.org有趣。它允许您对数据库架构进行版本控制。

#1 楼

除了其他答案...

首先捕获概念模型应该定义范围和要求。由此,您可以得出逻辑和物理数据模型。

一旦这大部分是静态的,那么您就可以使用一个稳定的数据库来构建您的应用程序。这与您的第一种选择相反。

第二点将以一个混乱且无法维护的泥球结束。数据模型将永远不会被修复:如果您没有预先设计它,那么您将没有时间在发货之前对其进行修复。您将太忙于将所有东西都一起砍掉。

对模式进行较小的更改,合并或拆分表,更改关系等都将发生,但是在本地化的“岛”中,您的模型和基本设计将保持不变。

评论


稳定性很重要,因为表和视图名称,列名称,存储过程名称等是数据库的公共接口。 (迟早会有许多应用程序共享该接口。)

– Mike Sherrill的“猫召回”
2011年10月12日上午10:35

我会说这是一种非常理想的方法,我的经验是,不时发生急剧的变化,我们需要的是敏捷并迅速适应新需求并保持重构。

–缩放
2012年8月21日在5:44

@zinking:我现在正在做敏捷的事情。

– gbn
2012年8月21日在6:26

#2 楼

您将很难找到没有运行某种敏捷版本的任何现代软件部门。相比之下,DBA陷入了黑暗时代,以为@RobPaller的答案仍然很常见。

修改数据库模式从未像修改代码那样容易。不愿意采用敏捷方法进行数据库开发和维护。既然我们拥有与开发人员类似的操作工具和技术,我们绝对应该这样做。仅仅因为更改架构并不容易,并不意味着您不能,也不应该。

我不主张采用随意的数据库设计方法(请参见注释),只是更接近于敏捷开发团队的方法。如果您属于敏捷项目的一部分,则不会对将来可能会(或可能不会)进行的工作有任何要求,因此请针对需要的内容而不是可能的内容进行设计。

我想我对你的选择2投了赞成票,我怀疑我可能会对此感到冷漠!

评论


敏捷和数据库的确有一些警告。 VLDB的敏捷性是临界点:可能没有足够的时间来验证和测试可交付成果之间数十亿行表的更改。由于缺乏前瞻性,“敏捷开发”与“批发变更”不同

– gbn
2011年10月11日19:14

无法同意更多关于:缺乏深谋远虑的想法,但我认为这与问题无关。这与您是否应该轻而易举地进行设计无关,而与您的数据模型是否应该随着应用程序的发展而变化有关。 VLDB问题值得我进行编辑。

– Mark Storey-Smith
2011年10月11日19:33

我将问题读为“没有数据库的新应用程序”,而不是“需要更改数据库的现有应用程序”

– gbn
2011年10月11日19:36

同样,我在某处想念您的观点:)可以聊天吗?

– Mark Storey-Smith
2011年10月11日19:43



对于您的回答,一般的看法是+1,但是“修改数据库模式从未像修改代码那样容易”,这实际上取决于您拥有多少代码(以及代码有多旧)。国际海事组织相反的说法更普遍

–杰克·道格拉斯(Jack Douglas)
2011-10-12 6:41

#3 楼

我曾经奢侈地设计了几个中等复杂性数据库,所有这些数据库都用于企业中,并具有包括Web,Access和C#在内的各种前端。

通常,我坐下来研究数据库预先计划。这对我来说总是最有意义的。但是,在任何情况下,我最终都没有做出更改,添加新表或生活在困扰我的方面,这些问题基本上为时已晚,无法修复。

我不认为解决方法是先编写代码。而且我不认为问题不是“业务需求不足”,或者至少不是一个可以完全解决的问题。用户不知道他们需要什么,我也没有能力使他们更努力地思考,变得更聪明或更清楚,或者更好地回答我的问题。或者他们争论不休,我被勒令以某种方式做某事。

我构建的系统通常位于从未有人涉足的新领域。我没有组织,资源或工具的支持,顶尖的专业设计人员的开发团队可以以团队赚取我十倍的薪水来完成这项工作两倍的时间。

我做的很好。但是,只有我一个人在“不进行开发”的环境中进行操作。

所有这些,我在发现业务规则方面越来越擅长。我看到了第三种选择:

在设计数据库之前,在编写任何代码之前,绘制粗略的屏幕以显示应用程序的工作方式。必须手工绘制它们,以防止任何人评论字体,大小或尺寸-您只需要功能。

使用透明胶片和纸片,您可以交换进出,有一个人是计算机,两个是非技术主题专家用户(两个可以大声说出来),一个人可以作为主持人来做笔记和画图向用户介绍他们的思维过程和困惑。用户“单击”并在框中拖动和写入,“计算机”更新屏幕,每个人都可以体验设计。您将学习到开发过程很长时间之前否则都不会学到的东西。但想法是先设计应用程序,而无需编写任何代码。我已经开始从小规模开始这样做,并且正在工作!尽管我的环境存在问题,但它可以帮助我从一开始就更好地设计数据库。我了解到列必须移入新的父表中,因为存在多种类型。我了解到工作清单必须具有不来自集成订单系统的常规订单。我学到了很多东西!

我认为这是一个巨大的胜利。

评论


+1好答案。在多个利益相关者项目中,便利的需求开发是巨大的。

–Zayne S Halsall
2015年6月5日7:38

#4 楼

逻辑数据模型应有效地捕获应用程序的业务需求。您的物理数据库设计应基于逻辑数据模型,并结合您作为DBA所感觉到的必要更改,以最大程度地提高RDBMS的效率。

如果发现必须进行在应用程序的整个软件开发生命周期中,对基础数据库设计进行了许多更改,这表明了两件事:

业务需求不足-您的数据建模人员(或系统分析人员)没有充分翻译业务分析师的要求。这导致数据模型不完整或不正确,无法支持您的应用程序需求。

说一旦将应用程序移交给生产环境,通常必须返回并进行迭代更改数据模型以支持应用程序或基础业务流程的自然发展。

希望这会有所帮助。

评论


在项目过程中添加许多新需求并不是“不合适的”。您的开发方法应该支持和鼓励这一点www.agilemanifesto.org/principles.html

– nvogel
2011年10月11日在21:05

我非常了解敏捷开发的一些原则,并且在数据仓库能力中对这些原则很拥护,这对于业务而言是有意义的。谢谢你的评论。

– RobPaller
2011-10-12 4:42

#5 楼

对于大多数目的,我会选择选项2:与其他组件并行构建数据库。尽可能地采用迭代方法,并在构建每个模块时提供端到端功能。

这确实需要一定数量的项目纪律。每次更改数据库时,请严格应用归一化(Boyce-Codd /第五范式),以便保持质量,而不会出现即席且不一致的模型。对于业务规则和附带的数据库约束,要尽可能地激进。如果有疑问,最好尽早实施约束-您随时可以将其删除。对实现体系结构组件的顺序保持明智,以最大程度地减少技术负担。有一套好的数据库设计指南,所有开发团队都可以使用。数据库透视图,创建测试数据。实际大小的数据的测试数据创建应在每次迭代中均应成功完成。

评论


您认为定义概念模型是否需要一些先期思考?

– gbn
2011年10月12日,0:09

进行一些先期思考可能会有用,但是尝试事先定义整个模型通常会适得其反。该模型应与业务需求保持一致,并随着项目的可交付成果(包括应用程序)而发展。您不能也不应该期望那些事情不会改变。由于需要创建虚拟接口以支持该架构的尚未使用的部分,因此预先创建整个模型实际上会阻碍其他开发。

– nvogel
2011年10月12日,0:26

我怀疑@dportas和我在类似的环境中工作:)

– Mark Storey-Smith
2011年10月12日,0:38

#6 楼

在建筑世界中,“形式跟随功能”一词被创造出来,后来在建造高层建筑时坚持使用。同样的方法也应适用于数据库基础结构和应用程序开发。

想象一下编写一个应用程序,即时确定您需要一个表和一个表。应用程序完成后,您将有大量表被视为数组。并排查看所有表,这些表肯定看起来没有任何韵律或理由。

不幸的是,一些开发人员商店会选择类似memcached的东西,并在RAM中加载数据(因此,像对待数据管道一样对待它),并拥有一个像MySQL或PostgreSQL这样的数据库,其行为就像是一个数据存储单元。 RDBMS。是的,一个关系数据库管理系统。使用RDBMS时,您的首要目标不仅应该是建立用于存储的表,而且还应该建立用于检索的表。表之间的关系应根据您要查看的数据及其显示方式进行建模。这应该基于数据的内聚性和完整性以及已知的业务规则。这些业务规则可以在您的应用程序(Perl,Python,Ruby,Java等)或数据库中进行编码。

结论

我肯定会选择选项1 。它需要适当的计划,数据建模和持续的数据分析。但是,从长远来看,这应该可以最大程度地减少数据库更改。

评论


@RolandoMySQLDBA,您假设在应用程序开发期间构建的数据库设计比以前构建的数据库设计差?为什么?事实恰恰相反。

– nvogel
2011年10月11日在21:48

@dportas:我的重点是选项1,它最大程度地减少了数据库设计中的更改。我花了2/3的技术职业生涯编程时间在商店中,这些商店几乎每个月都会一时兴起地改造非常复杂的数据模型和基础架构。我对这样的变化感到畏缩,因为业务需求和目标并不是一成不变的。我在这个学校很老。只要设计不会产生很多“技术债务”(是的,我读到你的回答),只要有点特立独行就没错。

– RolandoMySQLDBA
2011-10-12在1:12



+1表示“将RDBMS用作关系数据库而不是数组的位存储桶”-无论采用哪种方法

–杰克·道格拉斯(Jack Douglas)
11-10-12在6:44

@dportas:虽然这是正确的(业务规则更改),但是设计良好的数据库不会在迭代(或sprint或其他)与另一个之间进行根本性的更改,因为它反映了工作流程的所有相关数据结构。如果发生这种情况(根本变化),则意味着捕获活动的业务规则失败。

–Fabricio Araujo
2011年10月17日17:17

@dportas:不是所有数据库更改,只有RADICAL。较小的更改是做软件业务的一部分。但是在工作中不得不将数据拆分到2个不同的数据库中,这是设计和捕获业务规则的失败。 (实际上发生在我身上。

–Fabricio Araujo
2011-10-18 18:47

#7 楼

我牢记以下规则:“您只能从数据库中获取要生成的数据的信息”。因此,我先设计数据库,再设计代码。

为什么?无论我使用什么方法,语言/工具集,如果所有相关数据都经过精心设计并存储在数据库中,我都可以检索它。无论是在C#/ Delphi / FORTRAN / COBOL / Assembly / VBA还是Crystal Reports中; OO设计的或事件/数据/任何驱动的;敏捷或瀑布。如果有数据,并且我使用的工具可以连接到数据库,则可以检索数据。如果可以为该季度的收入选择订单,则可以创建销售报告-即使我必须在Assembly上逐字节写入它。

如果不存在相关数据,或者即使存在相关数据,但结构却以(我)无法获取所需信息的方式-如何编码?

#8 楼

我认为应该在应用程序没有任何实际代码之前完成,但在设计应用程序之前不应该这样做。

如果单独工作,我的典型工作流程是:


确定应用程序需要做什么
看看是否可以分解可重用组件的任何任务
确定每个任务如何与数据存储交互-什么样的问题他们要询问数据,它们要写多少次,等等。
设计数据库,以便它应该能够回答我们需要询问的所有问题,并且在执行最频繁的任务时应该表现良好。
编写应用程序。

当我经常作为团队的一员工作时,由于我们地域分散(在各个时区),我们倾向于召开首次启动会议:


确定应用程序需要做什么。
确定将应用程序分解为独立组件的优点是什么
确定每个组件如何nt将需要与其他人进行交互。
就每种交互方式都同意使用API​​。

然后,我们回到家,编写我们的部分,如果某个组件需要自己的本地组件,存储,只要该部分的维护者保持API与模块的一致性即可。主数据存储作为具有其自己的API的模块来处理,人们应该对此进行写操作。 (在DB速度至关重要的情况下,API是表定义,并且如果进行了更改,我们将使用视图或其他机制来呈现旧版本,直到可以更新所有模块为止)。

评论


选项2的情况是,使用敏捷方法时,除了下一个sprint的作用域之外,您不知道1、2或3。在范围,要求和期望方面,变化是不可避免的。

– Mark Storey-Smith
2011年10月13日20:45

#9 楼

通常,这取决于;)

例如,假设我们有一个使用Python开发并使用平面文件的小型工作原型,并且用户对原型的功能感到满意,因此我们需要做的是使用RDBMS作为后端来生产它。在这种情况下,可以期望第一次就做对,这是合理的-问题很小且定义明确。在这种情况下,预先设计是可行的。

另一方面,当我们在敏捷环境中发现需求时,我们需要进行一些迭代以更好地理解它们。在这种情况下,数据库随应用程序的其余部分一起发展。这就是我们通常要做的。因为我们可以重构活动的OLTP表而不会造成任何停机,而且风险很小,所以我们对数据库重构的可能性感到满意。