提问



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









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







回应指南:






保持您的清单简短。

每个答案的一个概念是最好的。


具体

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


解释您的理由。

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


Upvote您同意的答案。

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


不要因为它不适用于你个人而拒绝投票。

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

最佳参考


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


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


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


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


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


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


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


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


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


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


呼!

其它参考1


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



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

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

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

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

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

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

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

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

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

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

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


其它参考2


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


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


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


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


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


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


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


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


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


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


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

其它参考3


基本索引



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



  • 您的数据库中索引了哪些内容以及不是什么内容:

  • 扫描类型之间的区别,它们的选择方式以及编写查询的方式如何影响该选择;

  • 覆盖的概念(为什么你不应该写SELECT *);

  • 群集和非群集索引之间的区别;

  • 为什么更多/更大的索引不一定更好;

  • 为什么要尝试避免在函数中包装过滤器列。



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



  • Access反模式(逐列索引每一列)

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



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

其它参考4


正常化



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


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


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

其它参考5


索引如何工作



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


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


更有经验的开发人员可以编写相当好(和复杂)的SQL而不需要了解更多关于索引而不是索引使查询快速。[10]


这是因为SQL数据库执行非常好的工作作为黑盒子工作:



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



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


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


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


声明


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

其它参考6


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


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


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

其它参考7


避免SQL注入以及如何保护数据库[13] [14]

其它参考8


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


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


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


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


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


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

其它参考9


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


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

其它参考10


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


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



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

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

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



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


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


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


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


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


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

其它参考11


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


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


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


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


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


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

其它参考12


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


- 不同的数据类型:


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


- 了解1xM和MxM :


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


- K.I.S.S.原则也适用于DB :[17]


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


- 指数:


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





也:



  • 布尔代数是你的朋友

  • 图片:不要将它们存放在数据库上。不要问为什么。

  • 使用SELECT
  • 测试DELETE

其它参考13


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

其它参考14


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

其它参考15


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


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


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


至于问题本身:


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


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

其它参考16


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


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


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

其它参考17


简单的尊重。



  • 它不仅仅是一个存储库

  • 您可能不比供应商或DBA更了解

  • 上午3点你没有得到支持,高级经理对你大喊大叫


其它参考18


将非规范化视为一种可能的天使,而不是魔鬼,并将NoSQL数据库视为关系数据库的替代品。[18] [19]


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

其它参考19


切勿使用错误的文本编码插入数据。


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

其它参考20


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


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


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


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


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


了解您的数据库引擎执行过程并为其进行规划。

其它参考21


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


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


不幸的是,由于某种原因,它们今天似乎有所不同。人们希望.NET程序员知道字符串在C中是如何工作的,但是RDBMS的内部结构不应该太在意你。[20]


几乎不可能从阅读它们,甚至从顶部开始逐渐达到同样的理解水平。但如果从底部开始理解每一块,那么相对容易理解数据库的细节。甚至许多数据库爱好者似乎都不会犹豫不决,比如什么时候使用非关系型数据库。


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

其它参考22


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


第一列应该是其内容具有最大可变性的列(即基数)。


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

其它参考23


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


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


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


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

其它参考24



  • 基本的SQL技能。

  • 索引。

  • 处理DATE/TIME/TIMESTAMP的不同版本。

  • 您正在使用的平台的JDBC驱动程序文档。

  • 处理二进制数据类型(CLOB,BLOB等)


其它参考25


对于某些项目,面向对象的模型更好。[22] [23] [24]


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

其它参考26


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

其它参考27


RDBMS兼容性


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



  • 避免使用RDBMS SQL扩展

  • 消除触发器和存储过程

  • 遵循严格的SQL标准

  • 转换字段数据类型

  • 更改交易隔离级别



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

其它参考28


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

其它参考29


http://www.reddit.com/r/programming/comments/azdd7/programmers_sit_your_butt_down_i_need_to_have_a/[25]