分享

数据库设计中最常见的九大错误

 揽月86488 2019-02-28


我们在设计数据库时都希望避免犯一些低级错误。

身为数据库设计人员,当您负责数据库项目时,在设计过程中将数据库部署到生产环境之后,相信您一定会遇到一些挑战。

当然,其中一些问题是不可避免的,无法绝对控制。但是其中一些可以追溯到数据库设计本身的质量。数据库设计人员在第一步的设计阶段做出的决策会对数据库最终的运行情况产生深远之影响。

以下我们总结数据库设计中最常见的一些错误:

可怜的预先规划

如果您正准备建造房子,您不会立即雇用承包商并马上要求在一小时内开始建造地基,这会是一场灾难。最少的情况,您需要将计划和设计蓝图达成一致。

在数据库设计方面也需要遵守规则,保证没有任何问题。您的计划越好,设计输出的质量就越好。

一个好的数据库设计是仔细预计的结果,而不是临时想法的集合。糟糕的设计规划可能会导致结构问题,一旦数据库设计完毕,维护成本就会变得非常昂贵。

虽然并不能预测全数据库遇到的每个问题,但计划确保您可以将这些问题减少到只有那些真正不可避免的问题时为止。

未能理解数据的目的

创建数据库的目标有 很多。从存储个人数据的小型数据库到处理大量信息的大型企业数据库。设计人员必须了解数据库的目的,以便和目标的最佳匹配方式进行设计。

要提到的关键问题包括有:数据的性质,获取方式,存储和检索频率,存储数量以及使用它的应用程序。

在工作日结束时,手动输入数据的数据库不会像复杂的工业数据库那样在数据被自动实时捕获和存储的设计模型中飞速成长。

数据库设计的关键在于数据效率、可用性和安全性设计(可参见  PostgreSQL安全性)。忽略数据的目的将导致设计时勾选所有正确的选项,但实际上并不是很健全。

标准化不足

数据库设计并不是一个严格确定的过程。两位开发人员可以遵循相同的设计规则,但最终仍然会采用截然不同的数据布局。

这主要是因为任何软件工程项目中固有的创新地位。尽管如此,设计的某些核心原则让数据库以最佳方式运行至关重要。

其中一个重要原则就是数据库规范化。

规范化是指用于将表分解为标准组成部分的技术。您需要遵守此标准,让每个表只表示一个实体,而列描述表所表示项的属性。规范化是一个经典的计算概念,已经存在超过30年。

SQL主要用于读取和操作规范化数据集,因此更要我们深刻理解规范化,

SQL是一种固有的数据库语言,适用于构建一组结果或值。使用FROM子句,可以从一个表中提取数据,使用JOIN将其添加到另一个表的内容中。您可以使用几乎没有限量的表来生成所需的数据类型。SQL的功能对于数据库开发和性能亦至关重要。

当索引可以与键值完全同步时,索引效果最佳。当您必须使用LIKE,CHARINDEX,SUBSTRING和类似命令来解析与一列中的值组合的值时,SQL范例开始分解,并且数据的搜索次数越来越少。

因此,数据库规范化对于易于开发和始终如一的高性能非常之重要。

尽管如此,还是存在标准化的问题,也有存在过度规范化的数据库。良好的规范化应该平衡了记录插入,更新,查询和删除的需求。

最广泛接受的最佳实践是数据库必须至少标准化为第三范式(3NF)。但是,第四(4NF)和第五(5NF)范式也非常有用,更易于理解,一旦你知道如何使用它们就值得付出更多努力。

冗余记录

冗余表和字段是数据库设计人员和管理员的噩梦。他们利用系统资源来保证系统资源的安全性,最新数据和备份。当谈论十几个表左右时,冗余记录可能看起来不多。但是在冗余字段可能数千或数百万的大型数据库中,计算资源开销就会很大。它们不必要地增加了数据库的大小,从而降低了查询效率,而且增加了数据损坏的风险。

当然,有时可能需要冗余,这应该是例外情况,而不是规则。即使允许冗余,也应明确记录是什么原因,以确保在原因不再有效时由未来的数据库管理员删除之。

索引性能不佳

有时用户或应用程序可能需要查询表的多个列(字段)。随着表中行记录的数量增加,这些查询所需的时间将快速上升。为了加快查询速度并减少整个表大小的影响,谨慎的做法是对表中的列进行索引,以便在SELECT查询时,每个表中的条目几乎是立即可用。

不幸的是,加速SELECT函数通常会导致更多INSERT,UPDATE和DELETE命令的性能恶化。这很大程度上是因为:索引本身必须要不断地与数据库的内容同步,这反过来又意味着会有大量的数据库引擎开销。因此,加速SELECT查询的尝试可能会导致整体数据库速度变慢,这是过度使用索引的典型案例。

通过只为所有列提供一个索引并且与用于查询表的主键不同,可以解决此问题。您还可以从最常用到最少使用的列排序。索引始终是一个微妙的平衡,它归结为正确。

所有单个表的域值

无所不包的域表不是数据库设计的最佳方法。请记住,关系数据库是围绕这样的想法构建的,即数据库中的每个对象只代表一件事。任何数据集所引用的内容都不应该含糊不清。通过浏览主键,表名,列名和关系,可以快速解读数据集的含义。

尽管如此,对数据库设计的一种挥之不去的误解是,数据表越多,数据库就越混乱和复杂。

这通常是将几个表压缩到一个表中的原理,假设它能够简化设计。这听起来是个好主意,但通常以效率低下且难以操作的数据库结束。

SQL代码也将变长,难以阅读,就像把苹果和橙子混在了一起。乍一看,域表看起来像一个抽象的文本容器。从实现角度来看,这是正确的,但这不是设计数据库的最佳方式。

作为规范化过程的一部分,数据的隔离和分解在代表一件事的每一行中结束。每个域表都与所有其他域表不同。

多个域表的最终结果是:

  • 在查询中使用数据变得更加容易

  • 使用外键约束可以更自然验证数据,这对于单个域表设计是不切实际的。您可以使用单个域表执行此操作,但每个表所需的密钥会使维护成为雷区。

  • 每当需要添加有关某个对象的更多数据时,该任务就像添加一个或多个列一样简单。

  • 小域表适合硬盘的单个页面,而不像大型域表可能会跨多个磁盘部分进行扩展。将表放在单个页面中意味着可以通过单个磁盘读取来实现提取数据。

  • 拥有多个域表并不会阻止您为所有行使用一个编辑器。域表很可能具有相同的底层用法/结构。


命名不佳或不一致

数据库设计人员和开发人员经常将其角色视为技术角色。遵守命名约定等非技术方面往往会被推到优先级列表的较低层,甚至完全被忽略。这可能是一个灾难性的错误。

命名可能由设计人员自行决定,但事实上,它是数据库文档的第一个也是最重要的元素(我们将在下一个点探讨文档)。数据库设计者应该将工作看作是在他们转移到不同的雇主或角色后很长时间的东西。

命名约定旨在使没有参与项目的人更容易快速理解表和列的意思。未来的管理员,程序员或用户不应该浏览1000页的文档来理解某个表或列名称的含义。关于如何命名表的确切细节并未达到业界的一致同意。

命名最重要的是一致性。一旦您按照特定的方式命名对象,请在整个数据库中坚持使用它。表名称必须尽可能是表格所代表的完整或简约描述,而每个列名称应快速清楚表明它所代表的信息。对于简单的数据库,这并不难。但是,一旦构建相互关联的表,事情就会变得复杂。严格遵循命名约定始终是正确之方法。

这种约定包括对列或表名的长度不做字符限制,以便消除使用不容易理解或记住的首字母缩略词的需要。比如列名CUST_DSCR,任何阅读的人都需要对该列包含的内容进行猜测。CUSTOMER_DESCRIPTION将是一个更好的字段名称,并不会强迫读者扩展他们的想象力。

避免冗余 - 在名为“Students”的表中,当名称,地址和成绩足够时,您不需要将标记为StudentName,StudentAddress或StudentGrade的列名。

另外,不要使用保留字。将字段名起为“index”可能会令人困惑并成为错误的来源。相反,有一个描述性的前缀,如StudentIndex,这样就很好理解了。

文档编写很差

如果数据库开发和设计人员在确定命名约定的优先级时遇到问题,那么他们在文档方面也存在更大的问题。

对于开发人员来说,文档感觉像是开发过程中一个微不足道也非必要。但是,许多优秀设计的数据库就是在不良文档的祭坛上坏掉。糟糕的文档极大地限制了故障排除,结构改进,升级与连续性。

数据库设计者需要始终考虑他们在某些时间将不再参与数据库的支持。文档应该使其他人可以轻松地接管数据库设计,开发或管理。

良好的文档必须包含列,表,关系和约束定义,以明确每个元素的使用方式。如果您可以包含说明预期值的样本,则会产生更大的价值。

一些数据库设计者会使用较差的文档作为确保工作安全性的手段,即除了他们之外没有人可以完全理解数据库。这是一个短视和不合时宜的策略,它会导致管理层看不清设计者的意图。糟糕的文档使您更难以作为设计师多年后来优化或者进行代码改进。

测试不充分

您需要仔细地完成设计数据库所需的全部步骤。但是如果对数据库不进行严格的测试,那么可能陷入黑暗中。不巧的是,测试阶段是项目运行较晚时受影响最大的阶段。经常弄巧成拙的是,快速通过测试的数据库会被错误和不一致所困扰,这些错误却很容易在测试时被我们识别并解决掉。

充满错误的数据库不会被用户/管理员喜欢,即使它最终被修复,但仍然很难彻底从中把错误清除。在数据库上线之前进行深入和广泛的测试后,它会大大减少部署到生产后的故障数量。

完整的测试不会发现每一个bug,但它肯定会帮助人们摆脱大多数的问题。

结论

数据库开发和设计是任何数据密集型项目的核心,包括几乎所有业务应用程序。因此,应始终在此背景下进行数据库设计。

本文中列出的数据库设计错误,在一开始可能看起来都很小,微不足道。但最终,它们会显露出来,极大地降低数据库性能,修复成本也变得奇高。

当我们从一开始就很完善和一致性来完成任务,数据库设计者就可以构建更优秀的库结果,也符合项目或产品的合格预期,提高设计的成功率。

编译:洛逸

来源:21CTO社区

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多