每个开发人员应该了解数据库?

时间:2009-12-30 18:00:27

标签: database language-agnostic database-design

无论我们喜不喜欢,很多人(如果不是大多数)开发人员要么经常使用数据库,要么可能有一天必须使用数据库。考虑到野外滥用和滥用的数量,以及每天出现的数据库相关问题的数量,可以说开发人员应该知道某些概念 - 即使他们没有设计或使用数据库今天。所以:



开发人员和其他软件专业人员应该了解的有关数据库的重要概念是什么?


回应指南:


保持您的清单简短。
每个答案的一个概念是最好的。

具体
“数据建模”可能是一项重要的技能,但这恰恰意味着什么?

解释您的理由。
为什么你的概念很重要?不要只说“使用索引”。不要陷入“最佳实践”。说服您的观众了解更多信息。

Upvote您同意的答案。
首先阅读其他人的答案。一个排名较高的答案是比两个排名较低的答案更有效的陈述。如果您要添加更多内容,请添加评论或引用原始文件。

不要因为它不适用于你个人而贬低某些东西。
我们都在不同的领域工作。这里的目标是为数据库新手提供指导,以获得对数据库设计和数据库驱动开发的有充分理解和全面理解,而不是争夺最重要的标题。

31 个答案:

答案 0 :(得分:104)

开发人员应该首先了解数据库: 的数据库是什么?它们不是如何工作的,也不是如何构建的,甚至不是如何编写代码来检索或更新数据库中的数据。但它们的用途是什么?

不幸的是,这个问题的答案是一个不断变化的目标。 在20世纪70年代到90年代初的数据库中,数据库用于共享数据。如果您使用的是数据库,并且您没有共享数据,那么您要么参与学术项目或者你在浪费资源,包括你自己。设置数据库和驯服DBMS是一项艰巨的任务,就数据利用多次而言,回报必须与投资相匹配。

在过去15年中,数据库已用于存储仅与一个应用程序关联的持久数据。MySQLAccess构建数据库,或SQL Server变得如此常规,以至于数据库几乎已成为普通应用程序的常规部分。有时,随着数据的真实价值变得明显,最初的有限任务会被任务蠕变推升。遗憾的是,设计时只考虑一个目的的数据库在开始被推入企业范围和关键任务的角色时经常会失败。

开发人员需要了解的第二件事是全世界的以数据为中心的视图。与以流程为中心的世界观相比,以数据为中心的世界观与大多数开发人员所学到的不同。与此差距相比,结构化编程和面向对象编程之间的差距相对较小。

开发人员需要学习的第三件事,至少在概述中,是数据建模,包括概念数据建模,逻辑数据建模和物理数据建模。

概念数据建模实际上是从数据中心的角度进行需求分析。

逻辑数据建模通常是将特定数据模型应用于概念数据建模中发现的需求。关系模型的使用远远超过任何其他特定模型,开发人员需要确保学习关系模型。为一项重要的要求设计一个强大而相关的关系模型并非易事。如果您误解了关系模型,就无法构建好的SQL表。

物理数据建模通常是特定于DBMS的,除非开发人员也是数据库构建者或DBA,否则不需要详细了解。开发人员需要了解的是物理数据库设计与逻辑数据库设计的分离程度,以及通过调整物理设计可以实现高速数据库生成的程度。

开发人员需要学习的另一件事是而速度(性能)很重要,其他设计优度的衡量标准更为重要,例如修改和扩展数据库范围的能力在路上,或简单的编程。

最后,任何与数据库混淆的人都需要明白,数据的价值往往比捕获数据的系统要长

呼!

答案 1 :(得分:72)

好问题。以下是一些没有特别顺序的想法:

  1. 规范化,至少是第二种正常形式,至关重要。

  2. 参考完整性也很重要,具有适当的级联删除和更新注意事项。

  3. 正确使用检查约束。让数据库做尽可能多的工作。

  4. 不要在数据库和中间层代码中分散业务逻辑。选择一个或另一个,最好是中间层代码。

  5. 确定主键和群集密钥的一致方法。

  6. 不要过度索引。明智地选择你的指数。

  7. 一致的表和列命名。选择标准并坚持下去。

  8. 限制数据库中接受空值的列数。

  9. 不要被触发器带走。它们有它们的用途,但可以使事情匆忙复杂化。

  10. 小心使用UDF。它们很棒,但是当您不知道在查询中调用它们的频率时,可能会导致性能问题。

  11. 获取Celko关于数据库设计的书。这个男人很傲慢但知道他的东西。

答案 2 :(得分:22)

首先,开发人员需要了解有关数据库的知识。它们不仅仅是你放入SQL并获取结果集的神奇设备,而是具有自己的逻辑和怪癖的非常复杂的软件。

其次,出于不同目的,存在不同的数据库设置。如果有可用的数据仓库,您不希望开发人员从在线事务数据库中创建历史报告。

第三,开发人员需要了解基本的SQL,包括连接。

过去,这取决于开发人员的参与程度。我曾在那些我是开发人员和事实上的DBA的工作中工作过,而DBA就在那里,而DBA在他们自己的领域已经关闭了。 (我不喜欢第三个。)假设开发人员参与数据库设计:

他们需要了解基本规范化,至少是前三种常规形式。除此之外,还有一个DBA。对于那些对美国法庭有任何经验的人(以及这里的随机电视节目),有一个助记符“取决于钥匙,整个钥匙,除了关键,所以帮助你Codd。”

他们需要对索引有一个线索,我的意思是他们应该知道他们需要什么索引以及它们可能如何影响性能。这意味着没有无用的索引,但不要害怕添加它们来协助查询。应该为DBA留下更多的东西(比如天平)。

他们需要了解数据完整性的必要性,并能够指出他们验证数据的位置以及他们发现问题时他们正在做什么。这不一定在数据库中(很难为用户发出有意义的错误消息),但必须在某个地方。

他们应该掌握如何制定计划的基本知识,以及如何一般地阅读计划(至少足以判断算法是否有效)。

他们应该模糊地知道触发器是什么,视图是什么,以及可以对数据库进行分区。他们不需要任何细节,但他们需要知道向DBA询问这些事情。

他们当然应该知道不要干涉生产数据,生产代码或其他任何东西,他们应该知道所有源代码都会进入VCS。

我无疑忘记了一些事情,但普通的开发人员不一定是DBA,前提是有一个真正的DBA。

答案 3 :(得分:19)

基本索引

我总是很震惊地看到没有索引或任意/无用索引的表或整个数据库。即使您不是设计数据库而只是必须编写一些查询,至少要了解它仍然至关重要:

  • 您的数据库中包含哪些内容以及哪些内容未编入索引:
  • 扫描类型之间的差异,它们的选择方式以及编写查询的方式可能会影响该选择;
  • 报道的概念(为什么你不应该只写SELECT *);
  • 群集和非群集索引之间的区别;
  • 为什么更多/更大的索引不一定更好;
  • 为什么要尝试避免在函数中包装过滤器列。

设计师还应该了解常见的索引反模式,例如:

  • Access反模式(逐列索引每一列)
  • Catch-All反模式(所有或大多数列上的一个大型索引,显然是在错误的印象下创建的,它会加速涉及任何这些列的每个可能的查询)。

数据库索引的质量 - 以及您是否利用它编写的查询 - 将到目前为止占据了最重要的性能块。在SO和其他论坛上发布的10个问题中,有9个抱怨性能不佳,这总是归因于索引不佳或表达方式不合理。

答案 4 :(得分:16)

正常化

总是让我感到沮丧的是看到有人在努力编写一个过于复杂的查询,而这个查询在规范化设计(“显示每个地区的总销售额”)中完全是直截了当的。

如果您从一开始就明白这一点并进行相应的设计,那么您以后就会为自己省去很多痛苦。在规范化后,很容易对性能进行非规范化处理;规范化一个从一开始就没有这样设计的数据库并不容易。

至少,你应该知道3NF是什么以及如何到达那里。对于大多数事务性数据库,这是在使查询易于编写和保持良好性能之间的非常好的平衡。

答案 5 :(得分:14)

索引如何工作

这可能不是最重要的,但肯定是最被低估的话题。

索引编制的问题在于SQL教程通常根本不提及它们,并且所有玩具示例都没有任何索引。

更有经验的开发人员可以在不了解索引而不是“An index makes the query fast”的情况下编写相当好(且复杂)的SQL。

那是因为SQL数据库做了一个非常好的工作作为黑盒子工作:

  

告诉我你需要什么(gimme SQL),我会照顾它。

这非常适合检索正确的结果。 SQL的作者不需要知道系统在幕后做什么 - 直到一切都变得如此懒散......

当索引成为主题时。但这通常很晚,有人(某些公司?)已经遇到了真正的问题。

这就是为什么我认为索引是使用数据库时不要忘记的第一个话题。不幸的是,很容易忘记它。

<强>声明

这些论据来自我的免费电子书“preface”的Use The Index, Luke。我花了很多时间来解释索引如何工作以及如何正确使用它们。

答案 6 :(得分:12)

我只是想指出一个观察 - 这似乎是大多数响应假设数据库可以与关系数据库互换。还有对象数据库,平面文件数据库。评估手头软件项目的需求非常重要。从程序员的角度来看,数据库决策可以延迟到以后。另一方面,数据建模可以在早期实现并取得很大成功。

我认为数据建模是一个关键组件,是一个相对古老的概念,但它却被软件行业的许多人所遗忘。数据建模,尤其是概念建模,可以揭示系统的功能行为,并可以作为开发的路线图。

另一方面,可以根据许多不同因素确定所需的数据库类型,包括环境,用户量和可用的本地硬件,如硬盘空间。

答案 7 :(得分:11)

避免SQL injection以及如何保护您的数据库

答案 8 :(得分:9)

每个开发人员都应该知道这是错误的:“分析数据库操作与分析代码完全不同。”

传统意义上有一个明显的Big-O.当你执行EXPLAIN PLAN(或等效的)时,你会看到算法。一些算法涉及嵌套循环,并且 O n ^ 2)。其他算法涉及B树查找,并且 O n log n )。

这非常非常严重。理解索引的重要性至关重要。它是理解速度归一化 - 非规范化权衡的关键。了解数据仓库为何使用未针对事务更新进行规范化的星型模式至关重要。

如果您不清楚正在使用的算法,请执行以下操作。停止。解释查询执行计划。相应地调整指数。

另外,推论:更多指数不是更好。

有时,专注于一项操作的索引会降低其他操作的速度。根据两个操作的比例,添加索引可能会产生良好的效果,没有整体影响,或者对整体性能有害。

答案 9 :(得分:8)

我认为每个开发人员都应该明白数据库需要不同的范例

在编写查询以获取数据时,需要基于集合的方法。许多具有交互背景的人都在为此而斗争。然而,当他们接受它时,他们可以获得更好的结果,即使解决方案可能不是首先在他们的迭代焦点思维中出现的那个。

答案 10 :(得分:8)

很好的问题。让我们看一下,首先没有人应该考虑查询一个没有完全理解连接的数据库。这就像驾驶汽车而不知道方向盘和制动器在哪里。您还需要知道数据类型以及如何选择最佳数据类型。

开发人员应该理解的另一件事是在设计数据库时应该考虑三件事:

  1. 数据完整性 - 如果无法依赖数据,则基本上没有数据 - 这意味着不要在应用程序中放置所需的逻辑,因为许多其他源可能会触及数据库。数据完整性需要约束,外键和有时触发器。不要因为你不喜欢它们而不想使用它们,或者不想让它们理解它们。

  2. 性能 - 很难重构性能不佳的数据库,应该从一开始就考虑性能。有许多方法可以进行相同的查询,而且一些人知道几乎总是更快,不明白学习和使用这些方法是短视的。在设计查询或数据库结构之前,请阅读一些有关性能调优的书籍。

  3. 安全性 - 这些数据是贵公司的生命线,它还经常包含可能被盗的个人信息。学习如何保护您的数据免受SQL注入攻击,欺诈和身份盗用。

  4. 查询数据库时,很容易得到错误的答案。确保您彻底了解您的数据模型。请记住,通常根据查询返回的数据做出实际决策。如果错了,就会做出错误的商业决策。你可以从错误的查询中杀死一家公司,或者让一个大客户失去信数据具有意义,开发人员似乎常常忘记这一点。

    数据几乎永远不会消失,想想随着时间的推移存储数据而不是如何在今天获得数据。那个拥有十万条记录的数据库工作得很好,十年内可能不会那么好。应用程序很少会持续数据。这就是设计性能至关重要的一个原因。

    您的数据库可能需要应用程序不需要查看的字段。诸如复制的GUID,日期插入的字段之类的东西。您还可能需要存储更改历史记录以及更改历史记录以及何时能够从此仓库恢复错误更改。在你问一个网站如何解决你忘记在更新中放置where子句并更新整个表的问题之前,请考虑一下你打算如何做到这一点。

    永远不要在比生产版本更新的数据库版本中开发。永远不要永远不要直接针对生产数据库进行开发。

    如果您没有数据库管理员,请确保有人正在进行备份并知道如何恢复它们并已测试恢复它们。

    数据库代码是代码,没有理由不将其保存在源代码管理中,就像代码的其余部分一样。

答案 11 :(得分:6)

进化数据库设计。 http://martinfowler.com/articles/evodb.html

这些敏捷方法使数据库更改过程易于管理,可预测且可测试。

开发人员应该知道,在版本控制,持续集成和自动化测试方面重构生产数据库需要什么。

进化数据库设计过程具有管理方面,例如,在此代码库的所有数据库中,在一段生命周期后将删除一列。

至少知道,存在数据库重构的概念和方法。 http://www.agiledata.org/essays/databaseRefactoringCatalog.html

分类和流程描述也可以为这些重构实现工具。

答案 12 :(得分:5)

我会说强大的基本SQL技能。到目前为止,我见过许多开发人员,他们对数据库知之甚少,但总是在寻求有关如何制定一个非常简单的查询的技巧。查询并不总是那么容易和简单。在查询规范化的数据库时,您必须使用多个连接(内部,左侧等)。

答案 13 :(得分:5)

我希望所有人(包括DBA和开发人员/设计人员/架构师)更好地了解如何正确建模业务域,以及如何将业务域模型映射/转换为规范化数据库逻辑模型,优化物理模型,以及一个适当的面向对象的类模型,由于各种原因,每个模型都可以(可以)不同,并且理解它们何时,为什么以及它们如何(或应该)彼此不同。

答案 14 :(得分:5)

我认为这里已经涵盖了很多技术细节,我不想添加它们。我想说的一件事是社交而不是技术,不要因为“DBA知道最好的”陷阱而成为应用程序开发人员。

如果您遇到查询性能问题,请解决问题的所有权。做自己的研究并推动DBA解释正在发生的事情以及他们的解决方案如何解决问题。

完成研究后,也提出自己的建议。也就是说,我试图找到问题的合作解决方案,而不是将数据库问题留给DBA。

答案 15 :(得分:5)

关于以下对Walter M.回答的评论:

“写得非常好!对那些当时没有做数据库工作的人来说,历史观点非常好(即我)。”

历史观点在某种意义上绝对至关重要。 “那些忘记历史的人注定会重蹈覆辙。” Cfr XML重复过去的层次性错误,图形数据库重复过去的网络错误,OO系统强迫用户使用层次模型,而每个人甚至只有十分之一的大脑应该知道层次模型不适合一般 - 现实世界的目的表示,等等。

至于问题本身:

每个数据库开发人员都应该知道“Relational”不等于“SQL”。然后他们会理解为什么他们被DBMS供应商这么糟糕地放弃了,以及为什么他们应该告诉那些相同的供应商提出更好的东西(例如DBMS的真正的关系),如果他们想继续吸吮搞笑的数量这些糟糕的软件让他们的客户赚钱。)

每个数据库开发人员都应该了解关系代数的一切。然后就不再有一个开发人员不得不发布这些愚蠢的“我不知道如何做我的工作,并希望别人为我做这件事”的Stack Overflow上的问题。

答案 16 :(得分:5)

简单的尊重。

  • 它不仅仅是一个存储库
  • 您可能不知道比供应商或DBA更好。
  • 你不会在凌晨3点支持它,高级经理会对你大喊大叫

答案 17 :(得分:5)

根据我对关系数据库的经验,每个开发人员都应该知道:

- 不同的数据类型

为正确的工作使用正确的类型将使您的数据库设计更加强大,您的查询更快,生活更轻松。

- 了解1xM和MxM

这是关系数据库的基础。您需要了解一对多和多对多关系,然后在适当的时候应用。

- “K.I.S.S.”原则同样适用于数据库

简洁总是最好的。如果您已经研究过数据库如何工作,您将避免不必要的复杂性,这将导致维护和速度问题。

- 指数

如果你知道它们是什么,那还不够。您需要了解何时使用它们以及何时不使用它们。


也:

  • 布尔代数是你的朋友
  • 图片:请勿将其存储在数据库中。不要问为什么。
  • 使用SELECT
  • 测试DELETE

答案 18 :(得分:3)

除了他们使用的语法和概念选项(例如连接,触发器和存储过程)之外,对于每个使用数据库的开发人员来说,一件事情都是关键的:

了解您的引擎如何以特异性执行您正在编写的查询。

我认为这是如此重要的原因仅仅是生产稳定性。你应该知道你的代码是如何执行的,这样你就不会在等待长函数完成时停止线程中的所有执行,那么为什么你不想知道你的查询将如何影响数据库,你的程序,甚至可能甚至服务器?

这实际上是对我的R&amp; D团队的影响超过了丢失分号等。假设是查询将快速执行,因为它在他们的开发系统上执行,表中只有几千行。即使生产数据库的大小相同,也很可能会被更多地使用,因此遭受其他约束,例如多个用户同时访问它,或者其他地方的其他查询出现问题,从而延迟这个查询的结果。

即使简单的事情,例如联接如何影响查询的性能,在生产中也是非常宝贵的。许多数据库引擎的许多功能使概念上的操作更容易,但如果不清楚,可能会引入性能问题。

了解您的数据库引擎执行过程并为其做好计划。

答案 19 :(得分:3)

对于经常使用数据库(每天或几乎每天编写/维护查询)的中间道路专业开发人员,我认为期望应该与其他任何领域相同:你写了一个学院

每个C ++极客都在大学写了一个字符串类。每个图形极客都在大学里写过一个光线跟踪器。每个网络爱好者都在大学里写过互动网站(通常在我们有“网络框架”之前)。每个硬件书呆子(甚至软件书呆子)都在大学里建立了一个CPU。每个医生都在大学里解剖了整个尸体,即使她只是要承受我的血压并告诉我今天胆固醇过高。为什么数据库会有所不同?

不幸的是,由于某些原因,它们今天似乎有所不同。人们希望.NET程序员know how strings work in C,但是你的RDBMS的内部shouldn't concern you too much

几乎不可能只是阅读它们,或甚至从顶部开始工作,获得相同水平的理解。但是如果你从底层开始并理解每一块,那么找出数据库的细节就相对容易了。甚至许多数据库爱好者似乎也无法理解,比如何时使用非关系型数据库。

也许这有点严格,特别是如果你没有在大学学习计算机科学。我会把它调低一些:你今天可以写一个,完全从头开始。我不在乎你是否知道PostgreSQL查询优化器如何工作的具体细节,但如果你知道自己写一个,那么它可能与他们所做的不同。你知道,写一个基本的并不难。

答案 20 :(得分:3)

Denormalization视为可能的天使,而不是魔鬼,并将NoSQL databases视为关系数据库的替代。

此外,我认为即使您不设计数据库,实体关系模型也是每个开发人员都必须知道的。它会让你彻底了解你的数据库是什么。

答案 21 :(得分:3)

永远不要使用错误的文本编码插入数据。

一旦您的数据库被多种编码污染,您可以做的最好的方法是应用启发式和手工劳动的某种组合。

答案 22 :(得分:2)

  • 基本的SQL技能。
  • 索引。
  • 处理DATE / TIME / TIMESTAMP的不同版本。
  • JDBC driver您正在使用的平台的文档。
  • 处理二进制数据类型(CLOBBLOB等)

答案 23 :(得分:2)

非唯一索引中列的顺序很重要。

第一列应该是其内容(即基数)变化最大的列。

这有助于SQL Server在运行时如何使用索引创建有用的统计信息。

答案 24 :(得分:2)

了解用于编程数据库的工具!!!

我浪费了太多时间试图理解为什么我的代码神秘地失败了。

例如,如果您使用的是.NET,则需要知道如何正确使用System.Data.SqlClient命名空间中的对象。您需要知道如何管理SqlConnection个对象,以确保它们被打开,关闭,并在必要时正确处置。

您需要知道,当您使用SqlDataReader时,必须将其与SqlConnection分开关闭。您需要了解如何在适当时保持连接打开,以便最大限度地减少数据库的命中数(因为它们在计算时间方面相对昂贵)。

答案 25 :(得分:1)

三个(事物)是神奇的数字:

  1. 您的数据库也需要版本控制。

  2. 游标,您可能不需要它们。

  3. 触发器是邪恶的*

  4. *几乎总是

答案 26 :(得分:1)

对于某些项目,面向对象的模型更好。

对于其他项目,关系模型更好。

答案 27 :(得分:1)

答案 28 :(得分:1)

不要依赖SQL查询返回的行的顺序。

答案 29 :(得分:1)

RDBMS兼容性

查看是否需要在多个RDBMS中运行应用程序。如果是,可能需要:

  • 避免使用RDBMS SQL扩展
  • 消除触发器和存储过程
  • 遵循严格的SQL标准
  • 转换字段数据类型
  • 更改交易隔离级别

否则,应单独处理这些问题,并开发应用程序的不同版本(或配置)。

答案 30 :(得分:1)

阻抗不匹配问题,并了解常见的缺陷或ORM。