设计数据库的最简单和最有效的方法是什么?从我的角度来看,应用程序的数据存储设计有几个选项:
根据您的经验,您认为最有成效和最有效的方法是什么?
gbn*_*gbn 43
除了其他答案...
首先捕获您的概念模型应该定义范围和要求。由此,您可以推导出逻辑和物理数据模型。
一旦这大部分是静态的,那么您就有了一个稳定的数据库来构建您的应用程序。这与您的第一个选择相反。
你的第二点将以一个凌乱、无法维护的泥球结束。数据模型永远不会被修复:如果你没有预先设计它,你将没有时间在发货前修复它。你会忙着一起破解事情。
对模式的细微更改、合并或拆分表、更改关系等都会发生,但在本地化的“孤岛”中,您的模型 + 基本设计将保持不变。
Mar*_*ith 27
您将很难找到任何不运行某些敏捷变体的现代软件部门。相比之下,DBA 被困在黑暗时代,@RobPaller 的答案包含的那种想法仍然很常见。
修改数据库架构从来没有像修改代码那么容易,这就是为什么人们不愿意采用敏捷方法来开发和维护数据库。既然我们拥有以与开发人员类似的方式操作的工具和技术,我们绝对应该这样做。仅仅因为改变架构并不容易,并不意味着你不能也不应该。
我不是在提倡一种随意的数据库设计方法(见评论),只是一种更接近敏捷开发团队的方法。如果您是敏捷项目的一部分,您将不会对将来可能(或可能不会)发生的工作提出要求,因此设计您知道需要的东西,而不是可能需要的东西。
我想这让我投票支持您的选项 2,我怀疑我可能会发现自己对这个选项感到冷淡!
Rob*_*ler 12
您的逻辑数据模型应该有效地捕获应用程序的业务需求。您的物理数据库设计应该基于逻辑数据模型,并结合您作为 DBA 认为最大化 RDBMS 效率所需的必要更改。
如果您发现在应用程序的整个软件开发生命周期中必须对底层数据库设计进行大量更改,这表明两件事:
话虽如此,一旦应用程序转入生产环境,必须返回并对数据模型进行迭代更改以支持应用程序或底层业务流程的自然演进并不少见。
希望这可以帮助。
Eri*_*ikE 12
我有幸设计了几个中等复杂度的数据库,所有数据库都用于企业,具有各种前端,包括 Web、Access 和 C#。
通常,我已经坐下来提前制定了数据库模式。这对我来说总是最有意义的。但是,没有一个案例是我最终没有做出更改、添加新表或忍受困扰我并且基本上来不及修复的方面。
我不认为解决方法是先编写代码。而且我不认为问题是“业务需求不足”,或者至少不是一个本来可以完全解决的问题。用户不知道他们需要什么,我也没有能力让他们更努力地思考、变得更聪明、更有意识或更好地回答我的问题。或者他们争论,我被命令以某种方式做某事。
我构建的系统通常位于以前没有人涉足的新领域。我没有来自组织的支持、资源或工具来完成顶级设计专业人士的开发团队所能完成的工作,他们作为一个团队的报酬是我在其中构建东西的十倍两倍的时间。
我擅长我的工作。但是只有我一个人在“不做开发”的环境中做这件事。
综上所述,我越来越善于发现业务规则。我看到了第三种选择:
在设计数据库和编写任何代码之前,绘制粗略的屏幕以显示应用程序将如何工作。它们必须是手绘的,以防止任何人评论字体、大小或尺寸——您只需要功能。
使用透明胶片和纸片,您可以换入和换出,一个人是计算机,两个是非技术主题专家用户(两个是他们大声说话),一个人在那里做笔记和绘图的协调员让用户了解他们的思维过程和困惑。用户“点击”并拖拽写在盒子里,“电脑”更新屏幕,每个人都可以体验设计。您将学到在深入开发过程之前无法通过其他方式学到的东西。
也许我自相矛盾——也许这是更好的需求发现。但这个想法是先设计应用程序,而不是编写任何代码。我已经开始小规模地做这件事了,它正在奏效!尽管我的环境存在问题,但它帮助我从一开始就更好地设计了数据库。我了解到一列必须移动到新的父表中,因为有多种类型。我了解到工作清单必须具有并非来自集成订单系统的长期订单。我学到了各种各样的东西!
在我看来,这是一个巨大的胜利。
nvo*_*gel 10
大多数情况下,我会选择选项 2:与其他组件并行构建数据库。尽可能采用迭代方法并在构建每个部分时提供端到端功能。
这确实需要一定数量的项目纪律。每次更改数据库时都严格应用归一化(Boyce-Codd / 第五范式),以保持质量并且不会以临时和不一致的模型结束。尽可能积极地处理业务规则和伴随的数据库约束。如果有疑问,最好尽早强制执行约束 - 您可以随时将其取消。了解实现架构组件的顺序,以最大限度地减少技术债务。拥有一套所有开发团队都接受的良好的数据库设计指南。
当然,所有这些都需要与其他良好的开发工程实践齐头并进:持续集成、测试自动化以及至关重要的从数据库的角度来看,创建测试数据。应在每次迭代中完成实际大小数据的测试数据创建。
在建筑界,“形式追随功能”这个词是创造出来的,后来在建造高层建筑时坚持使用。这同样适用于数据库基础设施和应用程序开发。
想象一下编写一个应用程序,即时决定你需要一张桌子,那里一张桌子。当您的应用程序完成后,您将有大量表被视为数组。并排查看所有表格,这些表格肯定会显得没有韵律或理由。
不幸的是,一些开发人员商店会选择像 memcached 这样的东西,在 RAM 中加载数据(因此将其视为数据管道),并拥有一个数据库,如 MySQL 或 PostgreSQL,仅作为数据存储单元运行。
使用数据库的动机应该是正确看待它:作为 RDBMS。是的,关系数据库管理系统。当您使用 RDBMS 时,您的目标不仅应该是建立用于存储的表,还应该是用于检索。表之间的关系应该根据您想要查看的数据及其呈现方式进行建模。这应该基于数据的内聚性和完整性以及已知的业务规则。这些业务规则可以在您的应用程序(Perl、Python、Ruby、Java 等)或数据库中编码。
结论
我肯定会选择选项 1。它需要适当的规划、数据建模和持续的数据分析。然而,从长远来看,这应该最大限度地减少数据库更改。
我记住了以下规则:“您只能从数据库中获取您有数据要生成的信息”。所以,我先设计数据库,后设计代码。
为什么?无论我使用什么方法/语言/工具集,如果所有相关数据都经过精心设计并存储在数据库中,我可以检索它。无论是在 C#/Delphi/FORTRAN/COBOL/Assembly/VBA 还是 Crystal Reports 中;面向对象设计或事件/数据/任何驱动;敏捷或瀑布。如果数据在那里,如果我使用的工具可以连接到数据库,我就可以检索它。如果我可以选择本季度收入的订单,我就可以创建销售报告——即使我必须在 Assembly 上逐字节地编写它。
如果相关数据不存在,或者即使它存在但(非)结构化,我无法检索我需要的信息 - 如何对其进行编码?
我认为它应该在应用程序的任何实际代码之前完成,而不是在应用程序设计之前完成。
如果单独工作,我的典型工作流程是:
由于我经常作为团队的一员工作,而且我们在地理上分散(并且跨时区),因此我们倾向于召开初始启动会议:
然后,我们回家,编写我们的部分,如果一个组件需要自己的本地存储,只要该部分的维护者保持其模块的 API 一致。主数据存储作为一个模块处理,有自己的 API,人们应该写入它。(在 DB 速度至关重要的情况下,API 是表定义,如果进行了更改,我们会使用视图或其他某种机制来呈现旧版本,直到所有模块都可以更新为止)
通常,这取决于;)
例如,假设我们有一个用 Python 开发并使用平面文件的小型工作原型,并且用户对原型的功能感到满意,那么我们需要做的就是将其生产化,使用 RDBMS 作为其后端. 在这种情况下,期望第一次就做对是合理的——问题很小而且定义明确。在这种情况下,预先设计是可行的。
另一方面,当我们在敏捷环境中发现需求时,我们需要几次迭代才能更好地理解它们。在这种情况下,数据库会随着应用程序的其余部分而发展。这就是我们通常所做的。因为我们可以在没有任何停机时间和低风险的情况下重构实时 OLTP 表,所以我们对数据库重构的可能性感到满意。