您应该在编写应用程序代码之前设计数据库吗?


57

设计数据库的最简单,最有效的方法是什么?在我看来,应用程序的数据存储设计有两个选项:

  1. 在编写任何应用程序代码之前,请尽可能最好地设计数据库。这为您提供了可以使用的基本数据结构的优点。我认为,这样做的缺点是您将进行很多更改,因为应用程序的具体细节会影响整个应用程序开发周期中数据的更改内容/位置/方式。
  2. 随着应用程序的实现,设计数据库。当您在编写应用程序时需要一些数据库对象时,可以与应用程序并行(按时间顺序)开发数据库。我所看到的好处是减少了对数据库结构的更改。缺点是应用程序代码和数据库开发之间的时间和开发工作的划分。

根据您的经验,您发现什么是最有效和高效的方法?


使用SDLC进行分而治之
Premraj 2015年

1
您可能会发现flywaydb.org有趣。它允许您对数据库架构进行版本控制。
托尔比约恩Ravn的安徒生

Answers:


41

除了其他答案...

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

一旦这基本上是静态的,那么您便有了一个稳定的数据库来构建您的应用程序。这与您的第一选择相反。

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

会对架构进行较小的更改,合并或拆分表,更改关系等,但是在局部的“孤岛”中,您的模型+基本设计将保持不变。


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

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

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

@gbn,很抱歉在这里提出以下问题。我不知道如何处理这种情况。请看看。stackoverflow.com/questions/46285924/…。请给我更好的解决方案。
RGS

27

您将很难找到没有运行某种敏捷版本的任何现代软件部门。相比之下,DBA处于黑暗时代,@ RobPaller的答案仍然很普遍。

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

我并不是在提倡一种偶然的数据库设计方法(请参阅注释),而只是一种更接近于敏捷开发团队的方法。如果您属于敏捷项目的一部分,则不会对将来可能(或可能不会)进行的工作有任何要求,因此请针对需要的知识进行设计,而不是可能的要求。

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


4
敏捷和数据库的确有一些警告。VLDB的敏捷性是临界点:可能没有足够的时间来验证和测试可交付成果之间数十亿行表的更改。而且由于缺乏
前瞻性

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

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

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

4
+1代表您的答案,但“修改数据库模式从未像修改代码那样容易”,这实际上取决于您拥有多少代码(以及代码有多旧)。国际海事组织(IMO),相反的
杰克·道格拉斯

12

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

如果发现必须在应用程序的软件开发生命周期中对基础数据库设计进行大量更改,则表明有两件事:

  1. 范围爬行 -您允许在不适当的时间引入新的要求。
  2. 业务需求不足 -您的数据建模人员(或系统分析师)没有充分转换业务分析师的需求。这导致数据模型不完整或不正确,无法支持您的应用程序需求。

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

希望这可以帮助。


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

1
我非常了解敏捷开发的一些原则,并且在数据仓库能力中对这些原则很拥护,这对业务很重要。谢谢你的评论。
RobPaller 2011年

11

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

通常,我已经坐下来并事先确定了数据库架构。这对我来说总是最有意义的。但是,在任何情况下,我最终都没有做出更改,添加新表或生活在困扰我的方面,并且基本上为时已晚,无法修复。

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

我构建的系统通常位于从未有人涉足的新领域。我没有从组织,资源或工具上获得支持的能力,一流的设计专业人员的开发团队可以像团队一样获得十倍于我的薪水来完成工作两倍的时间。

我做的很好。但是,只有我一个人在“不做开发”的环境中这样做。

综上所述,我在发现业务规则方面越来越好。我看到了第三种选择:

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

使用透明胶片和纸片,您可以进出交换,有一个人是计算机,两个是非技术主题专家用户(两个可以大声说出来),而一个人在那里可以做笔记和画画向用户介绍他们的思维过程和困惑。用户“单击”并在框中拖动和写入,“计算机”更新屏幕,每个人都可以体验设计。您将学习到开发过程很久以前否则还不会学到的东西。

也许我在矛盾自己-也许这是更好的需求发现。但想法是先设计应用程序,而无需编写任何代码。我已经开始从小规模开始这样做,并且正在工作!尽管我的环境存在问题,但它可以帮助我从一开始就更好地设计数据库。我了解到列必须移入新的父表,因为存在多种类型。我了解到工作清单必须具有不来自集成订单系统的常规订单。我学到各种各样的东西!

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


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

10

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

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

当然,所有这些都需要与其他良好的开发工程实践相结合:持续集成,测试自动化,以及从数据库角度来看至关重要的是创建测试数据。实际大小的数据的测试数据创建应在每次迭代中均应成功进行。


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

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

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

9

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

想象一下编写一个应用程序,即时确定您在这里需要一张桌子,在那儿需要一张桌子。应用程序完成后,您将有大量的表被视为数组。并排看所有桌子,这些桌子肯定没有韵律或理由。

不幸的是,一些开发人员商店会选择诸如memcached之类的东西,将其加载到RAM中的数据中(从而将其视为数据管道),并使诸如MySQL或PostgreSQL之类的数据库仅充当数据存储单元。

使用数据库的动机应该是正确看待它:作为RDBMS。是的,一个关系数据库管理系统。使用RDBMS时,您的首要目标不仅应该是建立用于存储的表,而且还应该建立用于检索的表。表之间的关系应根据您要查看的数据及其显示方式进行建模。这应该基于数据的内聚性和完整性以及已知的业务规则。这些业务规则可以在您的应用程序(Perl,Python,Ruby,Java等)或数据库中进行编码。

结论

我绝对可以选择选项1。它需要适当的计划,数据建模和持续的数据分析。但是,从长远来看,这应该使数据库更改最小化。


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

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

2
+1“使用RDBMS关系数据库不是有点桶数组” -无论接近你拿
杰克·道格拉斯

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

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

9

我认为应该在应用程序有任何实际代码之前完成,而不是在设计应用程序之前完成。

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

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

由于我经常作为团队的一员工作,并且我们地域分散(跨时区),因此我们倾向于召开首次启动会议:

  1. 确定应用程序需要做什么。
  2. 确定将应用程序分解为独立组件的优点
  3. 确定每个组件将如何与其他组件交互。
  4. 同意每个交互的API。

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


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

8

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

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

如果相关数据不存在或什至不存在,但其结构(非结构化)使我无法检索所需的信息-如何进行编码?


7

通常,这取决于;)

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.