数据库常见错误
作为数据库设计人员,当您承担数据库项目的任务时,可能会在设计过程中以及将数据库部署到生产中后遇到一些挑战。
其中一些问题是不可避免的,超出了您的控制范围。 但是,其中许多可以追溯到数据库设计本身的质量。
您在此初步阶段做出的决定可能会对数据库的最终运行状况产生深远的影响。 以下是数据库设计中的一些最常见错误。
预计划不佳
如果您要盖房子,则不会雇用承包商,而是立即要求他们在一小时内开始打基础。
那将是一场灾难。 至少,您需要就房屋计划和蓝图达成协议。 在数据库设计方面没有什么不同。
规划越好,设计输出的质量就越高。
一个好的数据库是经过深思熟虑的结果,而不是临时思想的综合。
设计不良的计划可能会导致结构性问题,一旦推出数据库,解决这些结构性问题的成本将非常高昂。
并非总是能够预料到数据库会遇到的每个问题,但是进行计划可确保您可以将这些问题减少到只有真正不可避免的问题。
无法理解数据的目的
创建数据库的目的很广泛。 从存储个人个人数据的微型数据库到处理大量信息的大型企业数据库。
设计人员必须了解数据库的目的,以便以最佳方式与这些目标保持一致的方式进行设计。
要问的关键问题包括数据的性质,如何获取,存储和检索的频率,数据量以及将使用哪些应用程序。
在工作日结束时手动键入数据的数据库将无法与复杂的工业数据库(在该数据库中自动且实时地捕获和存储数据)在相同的设计模型下发展壮大。
关键在于确定可确保数据效率,可用性和安全性的设计(请参阅postgresql security )。 忽略数据的用途将导致设计打勾所有正确的框,但实际上是不合理的。
归一化不足
数据库设计不是严格的确定性过程。 两名开发人员可以遵循完全相同的设计规则,但最终仍会获得截然不同的数据布局。
这在很大程度上是因为在任何软件工程项目中,创造力都是固有的。
但是,某些设计核心原则对于确保数据库以最佳状态运行至关重要。 这些原则之一是规范化。
规范化是指用于将表分解为组成部分的技术。
直到每个表仅代表一件事,而各列描述表所代表的项的属性之前,您要这样做。
规范化是一个古老的计算概念,已经存在了超过3年。
实际上,SQL主要是为了读取和操作规范化数据集而创建的。 为了理解规范化,因此查看SQL的工作方式将很有帮助。
SQL是一种固有的加性语言,旨在轻松建立一组结果或值。
使用FROM子句,您可以从一个表中提取数据,并使用JOIN将其添加到另一表的内容中。
您可以使用几乎无限数量的表来生成所需的数据类型。
SQL的附加功能对于数据库开发和性能至关重要。
索引可以完全与键值同步时,它们的工作效果最佳。
当您必须使用LIKE,CHARINDEX,SUBSTRING和类似命令来解析与一列中的值组合的值时,SQL范式开始瓦解,并且数据的搜索量越来越少。
因此,规范化数据库对于简化开发和始终如一的高性能至关重要。
但是,存在标准化的层次,并且存在数据库过度标准化的情况。 良好的规范化可以平衡记录插入,更新,查询和删除的需求。
最广泛接受的最佳实践是,数据库至少必须规范化为第三范式(3NF)。
但是,第四个(4NF)和第五个(5NF)可能非常有用,易于理解,一旦您知道如何使用它们就值得付出努力。
冗余记录
冗余表和字段是数据库设计人员和管理员的噩梦。
它们利用系统资源来确保它们的安全性,最新性和备份性。 当您只谈论十几个记录时,冗余记录可能看起来并不多。
但是在大型数据库中,冗余字段可能会数以千计或数以百万计,计算资源开销非常大。
它们不必要地增加了数据库的大小,从而降低了效率并增加了数据损坏的风险。
当然,有时可能需要冗余,但这应该是例外,而不是规则。
即使允许冗余,也应清楚记录原因,以确保当原因不再有效时,将来的数据库管理员可以将其删除。
索引编制不良
有时,用户或应用程序可能需要查询表的许多列。
随着表中行记录数量的增加,完成这些查询所花费的时间将稳定增长。
为了加快查询速度并减少整体表大小的影响,谨慎的做法是为表列建立索引,以便在调用SELECT查询时几乎每个列中的条目都立即可用。
不幸的是,加快SELECT函数的速度通常会导致更常规的INSERT,UPDATE和DELETE命令的性能下降。
这主要是因为索引本身必须始终与数据库内容保持同步,这又意味着大量的数据库引擎开销。
具有讽刺意味的是,因此,您尝试加快SELECT查询的速度可能会导致整体数据库速度变慢。 这是过度索引的经典情况。
只需为所有列设置一个索引即可解决此问题,该索引不同于用于查询表的主键。
您还可以从使用最多到使用最少的列进行排序。 索引编制始终是一个微妙的平衡,归结为正确无误。
所有域值的单个表
包罗万象的域表并不是数据库设计的最佳方法。
请记住,关系数据库是围绕数据库中的每个对象仅代表一件事的想法构建的。
任何数据集所指的内容都不应有歧义。
通过浏览主键,表名,列名和关系,应该快速理解数据集的含义。
仍然,关于数据库设计的一个挥之不去的误解是表越多,数据库将越混乱和复杂。
这通常是将多个表压缩为一个表的基本原理,其前提是它将简化设计。
听起来不错,但通常以效率低下且笨拙的数据库结尾。
SQL代码将耗时,难以阅读且不自然。 它将有效地混合苹果和橙子。
乍一看,域表看起来像是文本的抽象容器。
从实现的角度来看,这是正确的,但不是设计数据库的最佳方法。
作为规范化过程的一部分,数据的隔离和分解在仅代表一件事的每一行中结束。 每个域表都与所有其他域表不同。
多个域表的最终结果是:
- 在查询中使用数据变得更加容易
- 可以使用外键约束更自然地验证数据,这对于单域表设计是不切实际的。 您可以使用单个域表来执行此操作,但是每个表所需的键会使维护成为一个雷区。
- 每当您需要添加有关某个对象的更多数据时,任务就像添加一个或多个列一样简单。
- 小域表将适合硬盘的单个页面 ,而大域表可能会散布在多个磁盘部分中。 将表放在单个页面中意味着可以通过一次磁盘读取就可以提取数据。
- 拥有多个域表并不能阻止您对所有行使用一个编辑器。 域表很可能具有相同的基础用法/结构。
命名约定不佳或不一致
数据库设计人员和开发人员经常将他们的角色完全视为技术角色。
诸如遵循命名约定之类的非技术性方面往往被推到优先级列表的下层,甚至被完全忽略。 这可能是一个灾难性的错误。
命名可能由设计人员决定,但实际上,这是数据库文档的第一个也是最重要的元素(我们将在下一点探讨文档错误)。
数据库设计人员应该将他们的工作视为可以转移到其他雇主或职位上的很长时间。
命名约定旨在使根本不参与项目的人员更容易快速了解表和列的内容。
将来的管理员,程序员或用户都无需浏览1000页的文档即可了解某个表或列名的含义。
业界并未就如何命名表的确切细节达成一致意见。
不过,最重要的是一致性。 按照特定的命名方式命名对象后,请在整个数据库中坚持使用。
表名称必须尽可能是表代表的完整描述或合同描述,而每个列名称应Swift使表述清楚。
对于简单的数据库,这并不难。 但是,一旦建立相互引用的表,事情就会变得复杂。 严格遵循命名约定始终是正确的方法。
这样的约定包括对列或表名的长度没有字符限制,以便消除使用不容易理解或记住的首字母缩略词的需要。
考虑列名CUST_DSCR。 任何阅读该书的人都将不得不对该列所包含的内容进行疯狂的猜测。 CUSTOMER_DESCRIPTION会是一个更好的列名,并且不会迫使读者花费更多的精力。
避免冗余-在名为“ Students”的表中,当“名称”,“地址”和“成绩”就足够时,您不需要具有标有“学生姓名”,“学生地址”或“学生成绩”的列。
另外,请勿使用保留字。 将列标记为“索引”可能会造成混淆,并且会导致错误。 而是使用描述性前缀,例如StudentIndex。
文档不良
如果数据库开发人员和设计人员在确定命名约定的优先顺序时遇到问题,则他们在文档方面的问题要大得多。
对于开发人员而言,文档有时感觉像是开发过程中琐碎的非必需方面。
然而,许多本来设计出色的数据库却因糟糕的文档而died折。 不良的文档极大地阻碍了故障排除,结构改进,升级和连续性。
数据库设计人员必须始终想像,他们将在某个时候不再参与数据库的支持。
该文档应使其他人可以轻松地接管数据库的设计,开发或管理。
好的文档必须包含列,表,关系和约束的定义,以使每个元素的使用方式变得清晰。
如果您可以包含说明期望值的示例,则将产生更大的影响。
一些设计师会使用不良的文档来确保工作安全,即没有人,但他们可以完全理解数据库。
这是一种短视且注定要失败的策略,因为它几乎总是导致管理人员了解设计师的意图。
糟糕的文档也使您更难,因为设计师在多年后返回并重新设计和改进代码。
测试不足
您可以精心完成设计世界一流数据库所需的所有步骤。
但是,如果不对数据库进行严格的测试,您将一头雾水。
不幸的是,当项目运行较晚时,测试阶段是受苦最大的阶段。
但是,这是自欺欺人的,因为快速进入的数据库将立即被在测试阶段很容易识别和解决的错误和不一致所困扰。
充满错误的数据库不会吸引用户和管理员,这是一个声誉坑,即使最终修复了这些错误,您也很难摆脱困境。
如果在数据库上线之前进行了深入而广泛的测试,则可以大大减少部署到生产后的故障数量和规模。
良好的测试不会找到每个错误,但可以肯定的是,它可以帮助您摆脱大多数错误。
数据库开发和设计是任何数据密集型项目(包括几乎所有业务应用程序)的核心。
因此,应始终在这种情况下查看设计过程。
本文中列出的设计错误在开始时似乎很小,而且微不足道。
但是最终,它们极大地降低了数据库性能,并且修复成本很高。
通过确保一开始就可以解决问题,可以增加构建非常适合其预期目的的数据库的几率。
翻译自: https://www.javacodegeeks.com/2019/01/common-mistakes-database-design.html
数据库常见错误