什么是数据库模式?
这其实是一个有点难回答的问题像许多数据库术语一样,数据库模式一词在各种情况下被使用。根据不同的语境,它可能意味着不同的东西。
在一般讨论数据库及其组织方式的情况下,数据库模式一词描述了数据的结构以及数据库中的元素如何相互关联。这些信息通常以图表的形式呈现,说明不同的表和元素是如何连接的,让你对整个数据库有一个合理的看法。然而,模式本身存在于数据库中,是定义数据结构和关系的编码规则。
在这种情况下,数据库模式通常是在创建一个新的数据库之前就已经计划好的东西。它反映了你的数据库的设计,最好是在你开始建设之前就进行设计!架构师或开发人员根据数据模型或应用程序考虑需要什么,然后对将包括的表、数据类型、外键约束等做出决定。最终的设计被称为数据库模式。
总而言之,一个数据库模式。
- 定义了数据库中的数据是如何结构化的
- 定义数据库中的元素是如何相互关联的
- 通过实施编码规则来完成上述工作
在这篇文章中,我们将主要关注上述数据库模式的定义,因为架构师和开发人员必须在创建和实现数据库之前仔细思考他们的模式设计。但首先,为了避免混淆,我们需要了解数据库模式这一术语的其他几种使用方式。
"数据库模式 "的其他定义
在SQL数据库中,数据库模式这一术语还可以有另一种更具体的含义。术语 "模式 "有时被用来表示一组命名的数据库对象。这种类型的模式更确切地称为用户定义的模式,所以为了避免混淆,我们将在本文的其余部分使用这个术语。
一个数据库可以有多个用户定义的模式,不同的用户定义的模式可以用来让不同的用户或用户组访问数据库的不同部分。
例如,假设我们有一个物流团队,我们想让他们访问orders 和shipments 表,同时不让他们访问我们customers 表中的 PII(个人身份信息)。我们可以通过创建一个名为logistics 的用户定义模式来做到这一点,该模式只包含我们希望物流团队能够访问的数据库对象(orders,shipments )。
回顾一下,一个用户定义的模式是。
- 用户选择的数据库对象的集合,如表、视图等。
- 有助于安全和访问管理
数据库模式这一术语有时也用来指其他东西,如提供数据库可视化表示的流程图(即实体关系图,或ER图)。不过,为了本文的目的,我们要把重点放在 数据库模式的第一个定义上--在创建任何数据库之前,我们都需要考虑的大局性数据库设计。
那么像MongoDB这样的 "无模式 "NoSQL数据库呢?
从历史上看,使用具有定义模式的数据库管理系统的局限性之一是,由于模式强制执行结构,所以很难存储非结构化的数据。另一个限制是,在数据库投入生产后改变数据库的模式需要停机。这意味着开发者要么在构建模式时要花很多心思,要么就得冒着为以后的修改付出沉重代价的风险。
"无模式 "的NoSQL数据库解决方案解决了其中的一些问题,但对于有大量事务性工作负载的应用来说,它们并不是一个好的解决方案,因为它们中的许多人都在为规模的一致性而奋斗。此外,开发人员为他们的应用程序设置NoSQL数据库时,必须确保在应用程序层面上对数据进行任何必要的约束,因为数据库本身没有一个模式来执行这些约束。
值得庆幸的是,现代分布式SQL数据库使开发者有可能 "既吃蛋糕又吃它"。例如,CockroachDB支持在线模式变更,这意味着开发者可以为他们的项目快速启动数据库,并随着时间的推移修改模式*,而无需*将数据库下线。CockroachDB还支持通过JSONB 数据类型来存储非结构化数据。
优秀数据库模式设计的最佳实践
根据你所使用的数据库,在你创建数据库之前仔细思考你的模式是相当重要的。虽然CockroachDB支持在线模式的改变,使得你可以很容易地调整你的模式,而不需要停机,但是对于传统的数据库来说,模式的改变会比较痛苦。
那么,你怎样才能在第一次就把它弄好呢?每个用例都是不同的,你的具体需求将决定你的数据库将如何设计。查阅与你自己的应用程序类似的数据库模式设计可能会有帮助。
但一般来说,这里有一些重要的事情需要考虑,以构建你的数据库模式。
整体结构
弄清楚你要存储的数据,然后开始将其分成表和列。这里的目标是完成一个有意义的结构,有主题组织的表和最小或没有重复的表。
命名规则
给你的表和列起一个描述性的名字,避免重复,比如把一个表叫做orders_table - 它应该简单地叫做orders 。你还需要避免在你的表、列等的名称中使用任何保留字。
约束条件
计划好你将添加到每个表中的约束,包括主键和任何外键。这是一个你要考虑到你所选择的数据库的领域,因为性能会有所不同。例如,虽然使用自动递增列作为主键对传统的单节点数据库来说效果很好,但如果你使用分布式数据库,如CockroachDB,这种方法往往会产生一个 "热点",即单个节点最终会处理大部分的工作负荷。为了分散工作负载并利用分布式架构的优势,最好使用自动生成的UUID或其他唯一的ID。
这只是一个例子。不管你使用的是哪种数据库系统,在你设计模式之前,了解主键和外键约束的最佳实践是个好主意。
数据类型
考虑你的列的适当的数据类型,牢记具有外键关系的列必须与父列共享相同的数据类型。在这里,看看是否有针对你的数据库技术的最佳实践也是明智的。例如,CockroachDB支持与时间相关的数据类型,包括TIME,TIMETZ,TIMESTAMP, 和TIMESTAMPTZ ,并建议使用TIMESTAMPTZ 作为最佳实践。其他系统可能支持并推荐其他格式。
索引
现在开始考虑性能问题永远都不会太早!为你预期用于排序或过滤数据的任何列创建二级索引是个好主意。也就是说,在这里不要太疯狂,因为有太多的索引会减慢写入性能,并吞噬可用的节点内存。
安全和加密
数据库的安全性是一个远远超出模式的考虑,如果你的数据库支持选择性加密,那么它也与模式设计有关。如果你的数据库支持它,对有PII的表进行加密,而将非敏感的表留在明文中,将使你在不影响安全的情况下从数据库获得最佳性能。
地理分区
将数据定位在靠近访问它的用户的地方是性能的最佳实践,将数据定位在用户所在的同一个国家也是某些国家的法律要求。如果性能和法规遵从对你的应用很重要,如果你有一个像CockroachDB这样的数据库,支持按表甚至按行进行地理分区,那么就值得考虑是否应该将特定的表与特定的地点联系起来,作为模式设计的一部分。
文档
可以说,与模式设计本身同样重要的是记录你的模式设计,以便其他人能够理解它。至少,你可能想要创建一个ER图,直观地说明你的数据库结构,以及一个数据字典,为数据库中的每个表和列提供额外的信息和背景。