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

Aar*_*ght 205 database language-agnostic database-design

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



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


回应指南:


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

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

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

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

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

Wal*_*tty 105

开发人员应该了解数据库的第一件事是:数据库是什么?它们不是如何工作的,也不是如何构建它们,甚至不是如何编写代码来检索或更新数据库中的数据.但它们是为了什么?

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

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

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

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

从数据中心的角度来看,概念数据建模实际上是需求分析.

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

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

开发人员需要学习的下一件事是,虽然速度(性能)很重要,但设计优度的其他衡量标准更为重要,例如能够在未来修改和扩展数据库范围,或简化编程.

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

呼!

  • 写得很好.而且我认为你的最后一点经常被那些试图"完成它"的人所忽视. (6认同)
  • @Walter你提供了除了这一点之外的所有要点的解释:"开发人员需要了解的第二件事是数据是整个以数据为中心的世界观.以数据为中心的世界观与以流程为中心的世界观不同于大多数开发人员都学过的东西.与这个差距相比,结构化编程和面向对象编程之间的差距相对较小." 你能详细说明一下吗?您说差距很大,但我想我真的想要了解以数据为中心的视图以及它与流程视图的分离方式. (3认同)

Ran*_*der 72

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

  1. 归一化,至少是第二种正常形式,是至关重要的.

  2. 通过适当的级联删除和更新注意事项,参照完整性也很重要.

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

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

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

  6. 不要超过指数.明智地选择你的指数.

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

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

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

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

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

  • @David:我总是喜欢把它放在两个地方.这样你就可以防止错误和用户错误.没有理由让每个列都可以为空,或者允许将1-12范围之外的值插入"Month"列.当然,复杂的业务规则是另一个故事. (9认同)
  • @David - 如果绝对确定数据库修改只会在应用程序中发生,那么你可能是对的.但是,这可能非常罕见.由于用户可能会直接将数据输入数据库,因此最好将验证也放入数据库中.此外,在数据库中更有效地完成某些类型的验证. (2认同)

Dav*_*ley 22

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

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

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

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

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

他们需要对索引有一个线索,我的意思是他们应该知道他们需要什么样的索引以及它们可能如何影响性能.这意味着没有无用的索引,但不要害怕添加它们来协助查询.应该留给DBA更进一步(比如余额).

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

他们应该具备如何获得计划的基本知识,以及如何一般地阅读它(至少足以判断算法是否有效).

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

他们当然应该知道不要干涉生产数据,生产代码或类似的东西,他们应该知道所有源代码都进入了VCS.

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


Aar*_*ght 19

基本索引

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

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

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

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

数据库的索引的质量-你是否利用它与你写的查询-占目前为止的表现最为显著块.在SO和其他论坛上发布的10个问题中,有9个抱怨性能不佳,总是由于索引不佳或表达方式不合理.


Aar*_*ght 16

正常化

总是让我感到沮丧的是看到有人在努力编写一个过于复杂的查询,而这个查询在规范化设计中会非常简单("显示每个区域的总销售额").

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

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


Mar*_*and 14

索引如何工作

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

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

更有经验的开发人员可以在不了解索引的情况下编写相当好(和复杂)的SQL而不是" 索引使查询快速 ".

那是因为SQL数据库在黑盒子方面做得非常好:

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

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

这就是索引成为主题的时候.但这通常很晚才有人(某些公司?)已经遇到了真正的问题.

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

放弃

这些论点来自我的免费电子书" 使用索引,卢克 " 的序言.我花了很多时间来解释索引如何工作以及如何正确使用它们.


Fer*_*doZ 12

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

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

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


iCh*_*aib 11

避免SQL 注入以及如何保护数据库


S.L*_*ott 9

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

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

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

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

另外,推论:更多指数并不好.

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


HLG*_*GEM 8

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

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

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

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

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

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

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

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

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

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

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


Rob*_*ley 8

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

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


Geo*_*voy 6

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

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

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

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

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

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


Cha*_*ana 5

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


Max*_*eat 5

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


Erw*_*out 5

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

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

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

至于问题本身:

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

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


Her*_*arn 5

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

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

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


gbn*_*gbn 5

简单的尊重.

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


Ana*_*nax 5

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

- 不同的数据类型:

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

- 了解1xM和MxM:

这是关系数据库的面包和黄油.您需要了解一对多和多对多关系,然后在适当时应用.

- " KISS "原则也适用于DB:

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

- 指数:

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


也:

  • 布尔代数是你的朋友
  • 图像:不要将它们存储在数据库中.不要问为什么.
  • 使用SELECT测试DELETE