数据库约束是什么?

99

数据库约束是什么?为什么约束对于数据库很重要?有哪些类型的约束?


13
这个问题有一个明确的答案,它不是“过于宽泛”的问题。它得到了大量赞和收藏,这表明它对许多人非常有用。我已经修改了措辞,并提议重新开放该问题。 - La-comadreja
@BasilBourque 这个问题对程序员来说非常不合适 - 它很快就会被投票否决和关闭,参见http://meta.programmers.stackexchange.com/questions/6483/why-was-my-question-closed-or-down-voted/6490#6490 推荐阅读:**Programmers.SE是做什么的?Stack Overflow指南** - gnat
1
@gnat 虽然那个页面让我对程序员堆栈交换的主题范围仍然感到困惑,但我可以理解并同意一个最低门槛,即发布者首先阅读了一个直接相关的维基百科文章,该文章提供了与在 Stack Exchange 上请求的相同类型的简明或概述概述。 - Basil Bourque
2
标题太宽泛了,而子问题一次性问了多个问题 -_- TomTom、Pரதீப்、greg-449、bummi和Nit想要什么?请解释一下。有没有办法可以询问约束条件呢...? - Lealo
尽管我理解对于问题过于宽泛和基于观点的看法,但我不同意首先阅读维基百科文章的要求。它并没有提供“相同类型的简明或概述性概览”。被接受的答案提供了比上面的维基百科链接更为简明和准确的答案。 - F.S.
9个回答

124

约束(Constraints)是数据库模式定义的一部分。

通常,约束与表相关联,并使用CREATE CONSTRAINTCREATE ASSERTION SQL语句创建。

它们定义了数据库中的数据必须符合的某些属性。它们可以应用于列、整个表、多个表或整个模式。可靠的数据库系统确保约束始终保持一致(除了在事务内,这种情况下被称为延迟约束)。

常见的约束类型包括:

  • 非空约束 - 列中的每个值都不能为 NULL
  • 唯一约束 - 指定列中的值对于表中的每行必须是唯一的
  • 主键约束 - 指定列中的值必须对于表中的每行是唯一的,并且不为空;通常,数据库中的每个表都应该有一个主键,用于标识各自的记录
  • 外键约束 - 指定列中的值必须引用另一个表中的现有记录(通过其 主键 或其他 唯一约束 )
  • 检查约束 - 指定一个表达式,该表达式必须评估为真以满足约束

3
+1 是为了包含PK,非空,可为空。 - gbn
+1,不过您可以扩展一下外键的场景,并提供一些链接。 - Unreason
2
检查约束条件不能为假。它们不一定要为真。未知也可以。 - Martin Smith
2
类型约束也是一种常见的类型吗? - Martin
1
虽然我们通常不称之为约束,但我认为数据类型是一种约束形式。如果我将某个东西定义为Int或datetime,那么就限制了可以放入该字段的数据类型。适当选择数据类型是确保数据完整性的关键部分。 - HLGEM

37
为了理解为什么我们需要约束条件,首先您必须明白数据完整性的价值。
数据完整性指的是数据的有效性。您的数据是否有效?您的数据是否代表您所设计的内容?
你可能会认为这是些奇怪的问题,但很不幸地,数据库常常充满了垃圾数据,对其他表中行的无效引用已经不存在了...还有一些对您的解决方案业务逻辑没有任何意义的值。
所有这些垃圾数据不仅容易降低您的性能,还是您应用逻辑下面的定时炸弹,最终将检索到它不应该理解的数据。
约束条件是您在设计时创建的规则,可以保护您的数据不被损坏。它对于您的数据库解决方案的长时间生存至关重要。如果没有约束条件,您的解决方案肯定会随着时间和重负而衰落。
你必须承认,设计你的数据库设计只是你解决方案的诞生。此后,它必须生存(希望)很长时间,并且忍受各种(奇怪的)行为,例如由最终用户(即客户端应用程序)产生的行为。但是,开发中的这个设计阶段对于您的解决方案的长期成功非常重要!尊重它,并为其所需的时间和精力付出努力。
有一位智者曾经说过:“数据必须保护自己!”这就是约束条件的作用。它是一种规则,可以使您数据库中的数据尽可能有效。
有许多方法可以做到这一点,但基本上它们归结为:
- 外键约束可能是最常用的约束条件,它确保只有在存在目标行时才允许对其他表的引用。这还使通过删除已被引用的行来破坏此类关系变得不可能,从而创建死链接。 - 检查约束可以确保只允许在特定列中输入特定值。例如,在VARCHAR列中仅允许输入“Yellow”或“Blue”的约束条件。所有其他值都将产生错误。获取有关检查约束使用方法的想法,请检查AdventureWorks示例数据库中的sys.check_constraints视图。
  • 规则在SQL Server中就是可重复使用的检查约束(允许您从一个地方维护语法,使得将约束部署到其他数据库更容易)
  • 正如我在这里所暗示的那样,构建数据库设计的最佳和最有防御性的约束方法需要仔细考虑。您首先需要了解上述不同约束类型的可能性和限制。进一步的阅读材料包括:

    FOREIGN KEY约束 - Microsoft

    外键约束 - w3schools

    CHECK约束

    祝您好运!;)


    作为一条死评论,似乎微软现在正在违反规则。 - gary

    7

    约束是关于数据的规则。可以使用约束来定义哪些数据是有效的,哪些是无效的。因此,可以维护数据的完整性。 以下是广泛使用的约束:

    1. 主键:唯一标识数据的约束。如果已为某个列指定了此约束,则无法在该列中输入重复数据。
    2. 检查:例如NOT NULL。在此处,我们可以指定可以为该特定列输入什么数据以及该列不期望的内容。
    3. 外键:外键引用其他表的行。因此,从另一个表引用到引用表的数据始终可用。

    3

    约束可以用来强制数据的特定属性。一个简单的例子是将int列限制在值[0-100000]之间。这篇介绍看起来不错。


    3

    约束规定了数据库中数据的有效值。例如,您可以强制一个值不为空(NOT NULL约束),或者它存在于另一个表中作为唯一约束(FOREIGN KEY约束),或者在此表中是唯一的(UNIQUE约束或根据您的要求可能是PRIMARY KEY约束)。更一般的约束可以使用CHECK约束来实现。

    SQL Server 2008约束的MSDN文档可能是您最好的起点。


    2
    1. UNIQUE约束(其中PRIMARY KEY约束是一种变体)。检查给定字段的所有值在整个表中是否唯一。这是X轴约束(记录)。

    2. CHECK约束(其中NOT NULL约束是一种变体)。检查同一记录的字段表达式是否满足某个条件。这是Y轴约束(字段)。

    3. FOREIGN KEY约束。检查一个字段的值是否在另一个表的字段值中找到。这是Z轴约束(表)。

    注:X、Y、Z轴分别代表三维空间中的三个方向,用于表示不同类型的约束所作用的范围。

    唯一约束和外键约束可以使用“CHECK”约束来编写,那么为什么要将其分类别呢?即“Y-axis”(不管它是什么意思)。 - onedaywhen
    2
    @onedaywhen:你如何使用CHECK约束来实现FOREIGN KEY - Quassnoi
    1
    @onedaywhen:尝试使用这个约束条件创建一个表。 - Quassnoi
    1
    @onedaywhen:尝试真的那么难吗?提示:这行代码不会起作用。 - Quassnoi
    3
    @onedaywhen:你写的查询语句并没有创建检查约束。它只是一个简单的SELECT查询。在SQL Server中,你不能在CHECK约束中使用子查询(或任何其他引用当前记录之外的值的结构)。 - Quassnoi
    显示剩余5条评论

    2

    SQL基本上有四种主要的约束类型:

    • 域约束:如果新元组提供的属性值之一不属于指定的属性域

    • 键约束:如果新元组中关键属性的值已经存在于关系中的另一个元组中

    • 引用完整性:如果新元组中的外键值引用了在被引用关系中不存在的主键值

    • 实体完整性:如果新元组中的主键值为null


    2
    数据库是一个计算机化的概念模型(或业务模型)的逻辑表示,由一组非正式的业务规则组成。这些规则是数据的用户理解的含义。因为计算机只能理解正式的表示,业务规则不能直接表示在数据库中。它们必须映射到一个形式化的表示,即逻辑模型,它由一组完整性约束组成。这些约束 - 数据库模式 - 是业务规则在数据库中的逻辑表示,因此是DBMS理解数据的含义。如果DBMS不知道和/或不执行代表业务规则的完整约束集,则意味着它对数据的含义有不完整的理解,因此无法保证(a)通过防止破坏来保持其完整性,(b)从中推断出的完整性(即查询结果) - 这是另一种说法,即DBMS在最好的情况下也是不完整的。
    注意:DBMS“理解”的含义 - 完整性约束 - 与用户理解的含义 - 业务规则 - 不完全相同,但是,尽管失去了一些含义,我们获得了从数据进行逻辑推断的能力。
    "An Old Class of Errors" by Fabian Pascal

    -1

    约束是可以验证特定条件的条件。

    与数据库相关的约束包括域完整性、实体完整性、引用完整性、用户定义的完整性约束等。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接