您如何进行数据库设计?[关闭]


14

我主要是一名Web开发人员,并且我要启动几个个人项目。

让我烦恼的一件事是数据库设计。我已经完成了学校的db规范化和类似工作,但是已经有两年了,除了学校,我从未有过关系数据库设计的经验。

那么,您如何从Web应用程序的角度来处理数据库呢?您如何开始?寻找什么?什么是警告标志?


8
Web应用程序的良好数据库设计与任何应用程序的良好数据库设计相同。有许多入门书籍可以很好地介绍基础知识。
罗伯特·哈维

1
@harvey您可能想推荐什么书?
bron 2010年

Answers:


14

我买过的关于数据库设计的最好的书是Michael Hernandez ISBN:0-201-69471-9撰写的《 Mor Mortals的数据库设计》亚马逊上市我注意到他有第三版。

链接到第三版

他将引导您完成设计数据库的整个过程(从头到尾)。我建议您从这本书开始。

您必须学会以小组或大块的眼光看待事物。就像编程一样,数据库设计具有简单的构建块。如果您对这些简单的构建块有透彻的了解,则可以解决任何数据库设计问题。

在编程中,您具有:

  • 如果构造
  • 如果其他构造
  • 循环执行
  • 直到循环
  • 案例构造

使用数据库,您可以:

  • 数据表
  • 查找表
  • 一对一关系
  • 一对多关系
  • 多对多关系
  • 主键
  • 外键

使事情变得越简单越好。数据库无非就是将数据放入笨拙的地方。首先确定这些小孔是什么,以及它们中需要什么样的东西。

第一次尝试时,您永远不会创建完美的数据库设计。这是事实。在此过程中,您的设计将进行一些改进。有时候,事情就不会显得明显,直到你开始输入数据,然后你有一个嗯哼时刻。

网络带来了自己的挑战。带宽问题。无国籍状态。来自已启动但从未完成的进程的错误数据。


11

我既进行面向对象的程序设计,也进行(主要是事务性的,但是有些OLAP的)数据库设计,并且就我的情况而言,有很多重复出现的主题(至少使用OLTP)。

练习3nf标准化有助于我练习单责任原则的某些变体。一张表应该代表您系统中的一个概念-概念应该相互关联,以使它们试图模仿现实。例如,如果我正在建立一个客户可以拥有0个或多个活动的系统,那么我将创建一个客户表和一个活动表。活动表与客户表具有外键关系。在构建存储过程时,我将确保使用外部联接来联接Customer和Activity,因为业务要求Customer可以有0个活动。

我还通过使用网桥(链接)表来注意可扩展性的机会。例如,如果我试图代表一个业务规则,其中一本书可以有无限(可变)的作者数量,那么我将创建一个Book Table,一个Author表和一个桥/链接表,该表具有对这两个表的外键引用书和作者。

此外,我在所有表上使用代理键(通常是自动递增标识列,但也许是Guids-与Guid在代码中的权衡是它们比一个简单的整数占用更多的内存空间),而且我避免依赖自然键查找(网桥/链接表除外)。默认情况下,我还会在公共外键列上创建索引,并不时查看存储过程/系统查询以优化索引策略。我使用的另一种索引策略是在代码中寻找基于搜索列构建集合的位置,并向搜索列添加适当的索引。


10

我先设计数据库架构,然后使用ORM从中创建对象。这样我有点老了。我不信任ORM创建智能,高效的数据库架构。那是人类的工作,也是软件设计工艺的一部分。


1
ORM不会发明您的架构。它基于您在对象中所做的工作来构建它。如果从架构中构建对象,则实际上是将重要任务委派给愚蠢的ORM。

1
@ Pierre303模式是根据ORM内的编程规则构建的,该规则可能无法与您的情况/设计完美结合。它可能会创建次优的数据库。我已经看到,即使在查询级别,ORM也会产生一些可怕的东西。
m4tt1mus 2012年

@ Pierre303,我认为此注释恰恰说明了为什么从ORm进行构建是个坏主意,一个正确设计的数据库不应直接与应用程序中使用的对象匹配。正确设计数据库通常还需要做许多其他事情,而这既不会考虑也不会考虑,因为考虑的是哪种结构对数据库而非应用程序最有效。
HLGEM 2012年

@HLGEM:您不可能使用过像Hibernate这样的高级ORM并写下该评论

OH,除了您的应用程序外,orm如何处理审核和其他所需的字段?
HLGEM

5

我发现Bill Karwin的书《SQL Antipatterns》对数据库规划非常有用。它最全面地说明了这一点,即数据库为保护数据的完整性和有意义性提供了许多机会,并且由于各种诱人的原因而忽略这些功能是设计人员的常见错误。从一开始就考虑这些问题,并让它们告知整个设计是值得的,并且比以后尝试解决裂缝要好。

我更喜欢使用具有全面约束的数据库在数据库级别实施业务逻辑和完整性。通常,我将数据库视为应用程序,而将其作为接口访问的所有内容。这使添加其他“界面”变得更加愉快和直接,并为安全性带来了积极的好处。

我还认为将数据库的结构视为一个不断变化的实体非常重要,而不是假定您需要先将其包装起来并密封起来再进行其他操作。您应该计划更改并在版本控制系统中容纳数据库。关于这一点,有一篇不错的文章:Martin Fowler和Pramod Sadalage撰写的Evolutionary Database Design(以及Sadalage撰写的关于该主题的整本书,尽管我没有读过)。

最后,用户帐户/角色,硬件/位置/主机连接等外围问题很重要,有时会被忽略。计划时也要牢记这些。


5

如果不考虑如何使用数据,就无法完全完成数据库设计,因此,这里列出了几步:

  • 写简短的句子,捕捉实体之间的关系
  • 绘制表示句子的实体关系图
  • 从ER图创建归一化逻辑数据模型
  • 为应用程序和实体创建CRUD矩阵
  • 使用矩阵来验证每个实体生命周期的覆盖范围
  • 为每种应用提取子方案
  • 检查每个主要/ CRUD操作在子方案上的导航路径
  • 考虑将需要的报告
  • 基于以上所有内容设计物理数据模型;适当地反规范化,分区和使用星型模式

如果计划取悦写支票的人,则最好确保您得到正确的报告。
JeffO

3

要成功设计数据库,您首先需要考虑以下几点:

  • 我需要存储什么数据,它与我存储的其他数据有什么关系。这些数据将如何随着时间变化?我是否需要能够及时查看快照(从2009年开始的顺序),还是仅需要当前快照(仅活动用户)?
  • 如何确定我的数据有意义并随着时间的推移保持含义(数据完整性)?
  • 如何确保数据访问速度快?
  • 如何保护我的数据安全?

因此,在开始设计数据库之前,首先需要了解规范化和用于保持数据完整性的数据库功能。

然后,您需要了解性能调整。这还为时过早,性能是大多数数据库的关键故障点,一旦拥有数百万条记录,就很难修复。

最后,您需要了解如何保护数据以及需要保护哪些数据以及需要采取哪些内部控制措施以确保数据不会被恶意更改,或者确保您可以随时间推移跟踪更改以找出谁和何时发生。进行了更改,并能够还原到以前的版本。

在开始之前,请先阅读一些有关重构数据库的信息,这对您很有帮助,因为稍后需要进行重构。了解如何进行设置以使您可以尽可能轻松地进行重构也很有帮助。

通常,数据比应用程序寿命长很多年,这是应用程序的核心,不应将其视为大多数无关紧要的愚蠢数据存储区。


2

一般而言,好的数据库设计就是好的数据库设计-Web使用的更大问题将是如何访问数据和管理人们可能认为需要的内容,而这些基本上是Web所没有的。

考虑一下,我的方法是基于相当多的经验……但是无论您是从模式还是对象开始,您实际上都是在尝试做相同的事情,即为数据建立可用的模型,在项目中,模型和模式之间可能存在相当直接的关系(并非在所有情况下,而且可能并非对所有表/对象都如此),因此,真正的问题是从您舒适的地方开始构建一个体面的模型,并从那里开始工作。

在建立一个体面的模型方面-@Tim可以将其用于数据库,从根本上来说,构建您的对象模型将大体上相似-独特之处,层次结构,多对多关系等等。进入数据库,请确保您做了所有的好事。

还要确保您在代码中包含脚本或ddl,以允许您从头开始创建架构并在进行更改时进行更新(代码中的ddl是我的首选方法-我有一个系统并且可以工作)。


2

我从一个大白板和一堆不同颜色的笔开始。不同的颜色意味着不同的事物。我才开始绘画。通常情况下,我用黑色表示一定的东西,可能用蓝色绘制一些东西,用绿色不太可能绘制一些东西。红色代表重要注意事项。我大量擦除和重画。我考虑要查询哪些类型的东西,并确保模型支持它。如果不是这样,我会进行调整直到它做完为止。

最终,如果模型太大,我将其移至Visio并重新放置在白板上。

最后,我考虑扩展点。我看到大多数人犯的最大错误是设计他们的数据库,然后说“我已经完成了数据库”,然后继续。您永远不会完成数据库。您收到的每个变更请求都可能一直下降到该级别。因此,请考虑如何添加它。考虑一下可能发生什么样的请求,看看您是否能够将它们挂钩。如果您根本不考虑可扩展性,那么当这些更改请求出现时,您将承担主要的设计债务。

至于“ SQL然后是ORM”,反之亦然,这取决于您。只需确保您的模型首先奠定了良好的基础。


棘手的是……我同意一个人需要考虑项目的未来(其余的都很好,因此值得投票),但是我不止一次拥有数据库,这些数据库的字段甚至表最终都没有被使用过,因为我设计的未来从未发生过。我现在倾向于大力构建以解决手头的问题-但是(这是我的“摆脱监狱”卡),我确保我有一种机制可以让我轻松地更新架构(由于我这样做是从代码可以在此过程中应用复杂的操作)
Murph 2010年

那正是我试图传达的。建立您所需要的,仅此而已。但是,如果您以后不打算进行扩展,那么,您是否曾经在高峰时段在湾区交通繁忙?这是当您不考虑可能需要扩展的情况时发生的完美示例。
Hounshell

为了更好地阐明颜色,我知道正确的是黑色。通常情况很简单,实际上没有任何其他可行的方案。蓝色代表我可能会决定略微重组的事情。事情可能是对的,但我可能会抹掉。绿色是我真正头脑风暴并且很可能会抹去的东西。
Hounshell

1

首先设计对象,然后使用ORM(例如nHibernate)创建架构。它比逆运算具有更多的灵活性。

下一步是优化生成的架构。

自从我看到一个首先设计数据库表的项目以来已经有很长时间了。


是。除非您是数据库专家,否则请确保数据库尽可能简单。它应该足以支持该应用程序。预优化是不好的。当您不知道自己在做什么时,进行预优化是很糟糕的。如果您遇到问题(也许不会),那就请一位真正的专家。
ElGringoGrande 2012年

1
@ElGringoGrande除非您是dbguru,否则您除了为最起码的应用程序设计数据库之外,没有其他业务。如果它将需要10个以上的表并且将不超过100000个记录,并且您没有专业的数据库设计人员,那么您做错了。
HLGEM

好废话 我设计了一个数据库,该数据库具有160多个表并具有数百万行(对于中等规模的客户,最大的表刚刚有超过100万条记录。最大的客户有500万以上)。大多数客户有数百个并发用户,最大的超过2000个用户。而且我不是DB Guru,也没有聘请一位。我已经针对多种不同的应用程序完成了其中几种数据库设计。男孩,我搞砸了。
ElGringoGrande 2012年

1
ElGringoGrande:如果您设计了这样的数据库,在表中有数百个并发用户和数百万行,并且用户很满意,那么您就是db-guru。也许您还没有意识到。
ypercubeᵀᴹ

1

到目前为止,其他人没有明确指出的几件事:

  • 最好由专业人士完成数据库设计。当然可以学习,但是如果不精通建模或数据库设计,我不建议您构建一个中型或大型模型。这样做的原因是错误设计的成本通常很高。

  • 充分了解系统目标和用户要求。在不了解需求的情况下,您将无法设计正确的数据模型。

  • 知道在程序中执行哪些代码以及让DB处理的代码。这是必需的,以便您正确设置数据列的null,非null等。这也是必需的,以便您正确指定RI。

  • 确定好您的主键。只要有可能,就去找简单的钥匙。

  • 考虑与其他应用程序的集成需求。

  • 考虑使用通用数据模型,并在命名和数据列大小方面遵循行业标准。

  • 考虑未来的需求(已知和适用时)

  • 让他人审查您的模式。

  • 使用建模工具-ERD工具或UML工具。

  • 查看并了解生成的DDL代码。不要认为这是理所当然的。

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.