YashanDB 数据完整性
本文内容来自 YashanDB 官网,原文内容请见 https://doc.yashandb.com/yashandb/23.3/zh/%E6%A6%82%E5%BF%B5%E6%89%8B%E5%86%8C/%E5%85%B3%E7%B3%BB%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E5%AE%8C%E6%95%B4%E6%80%A7.html
数据完整性主要是指数据库中的数据始终正确、一致且有效,数据完整性涉及各个方面,例如确保数据满足业务的定义和准则要求:身份证号必须是唯一的、员工的薪酬范围和职称存在某种关系、员工的居住地必须是存在的等。
在实际应用中,保证数据的完整性非常重要,通常可以通过在数据库应用程序中执行业务规则或通过数据库触发器触发存储过程等多种方法来保证数据完整性。
YashanDB 提供完整性约束功能,用于更便捷地从数据入库时就保证其完整性。
完整性约束是定义在列或对象上,用于限定数据库中的值必须遵守的规则(集)。数据库管理人员和业务程序开发人员明确声明数据完整性约束,以此来保证数据的完整性与业务正常运行。
使用完整性约束有以下优点:
易用:可以使用 SQL 语句定义完整性约束,而无需任何额外的编程。SQL 语句易于编写,同时也可以排除编程的错误。
规则集中且统一:完整性约束定义在表上,存储在数据字典中。所有关于表数据的业务程序操作都必须遵守统一的完整性约束,对约束规则的变动无感知。
灵活:加载大量数据时,可以临时停用完整性约束(待数据加载完成后再重新启用),减少/避免不必要的性能开销。
完整性约束的类型
YashanDB 数据库支持在列级和表级应用约束,在建表时,可以直接在关于列的描述后指定约束,也可以在整个建表语句末尾添加约束。
完整性约束可以分为如下类型:
# 非空约束
默认情况下,一个表中的所有列都允许空值,使用 NOT NULL 约束可以指定列不允许为空值。
NOT NULL 约束主要用于不能缺少值的列,例如员工信息表中的姓名列。如果姓名列指定了 NOT NULL 约束,在插入没有姓名的员工信息时会提示错误:
Copied!
如果表中已包含数据,不能再添加一个具有 NOT NULL 约束的列,除非对应列还带有 DEFAULT 值定义。
# 唯一约束
唯一约束规定了在指定列或列集中的每个值都是唯一的。即在一个表中,不允许多个行在有唯一约束的列(唯一键)或列集(复合唯一键)上具有重复值。
唯一键约束适合于任何不允许重复值的列,但唯一约束通常只要求值唯一,并不一定具有实际意义。
唯一约束列都为空值也始终满足唯一键约束。
# 主键约束
在一个主键约束中的列或列集,其键值能唯一地标识一行。每个表只能有一个主键,起确定行的作用,并确保不存在任何重复的行。
主键可以是表中有意义的属性列(例如身份证号),也可以是一个无意义的列(例如人为给表设置一个序列 ID 列)。
YashanDB 主键约束可以保证:
任何两行在指定的主键列上都不具有重复值。
主键列不允许为空值。
例如员工信息表中的编号标识,每个员工必须拥有唯一的 ID(工号),每名员工信息只能由员工表中的有且仅有的一行来记录:
Copied!
YashanDB 使用索引实现主键约束。通常,在某列上创建主键约束会隐含创建一个唯一索引和一个非空约束,但如果创建主键约束时已有一个现成的索引可用,则主键约束会直接复用该索引,不会隐式创建额外的新索引。
# 外键约束
当两个表拥有一个或多个公共列时,YashanDB 可以通过创建一个外键约束来建立这两个表之间的关联关系。
通常,外键约束要求约束列或列集中的每个值都必须与另一个表的指定列中的值相匹配,例如教师所带的班级必须是班级信息表中存在(教师信息表到班级信息表的外键约束)。
# 父表的修改与外键的关系
删除或更新父表数据可能会破坏外键约束。在父键被修改时,为了满足外键约束,参照完整性约束可以指定在子表中的相关行上,执行以下某种操作之一:
NO ACTION
在正常的情况下,如果修改结果会违反外键约束,用户不能做此修改。
DELETE CASCADE
级联删除(DELETE CASCADE)是指当父表被删除时,对应被引用键值在子表中的所有行也同时被删除。
DELETE SET NULL
删除置空(DELETE SET NULL)是指当父表被删除时,对应被引用键值在子表中的所有行的外键被设置成 NULL。
UPDATE CASCADE
级联更新(UPDATE CASCADE)是指当父表更新时,对应被引用键值在子表中的所有行也同时按照新值更新。
UPDATE SET NULL
更新置空(UPDATE SET NULL)是指当父表更新时,对应被引用键值在子表中的所有行的外键被设置成 NULL。
# 索引和外键
YashanDB 建议在外键列上创建索引,优势如下:
可以防止修改父表触发子表的排他表锁。
可以防止修改父表触发子表的全表扫描。
# 检查性约束
检查约束具备强制执行具体的完整性规则的能力,对指定列或列集创建检查性约束,可以保证表中的数据一定满足指定的条件。如果 DML 语句违反了检查性约束的条件,执行会报错。
在 age 列中设置不能大于 60 的检查约束,插入示例如下:
Copied!
允许对同一列同时指定多个检查性约束,但应保证所有检查性约束的合理性,否则可能会导致表不可用。例如:某一列同时被指定“值必须大于 5000”和“值必须小于 4999”,两个检查性约束互斥,设置不合理。
完整性约束的表现
YashanDB 可以指定将某个约束是否启用(对象是新数据)和是否验证(对象是现有数据),从而确定具体的约束表现。
如果指定启用(ENABLE),插入/更新数据时会检查新数据是否符合约束,违反约束的数据无法插入/更新至表中。
如果指定验证(VALIDATE),会验证现有数据是否符合该约束。如果现有数据存在违反约束,则指定验证(VALIDATE)失败并报错。唯一约束以及主键约束由唯一索引保证,即使指定为不验证(NOVALIDATE)依然会验证,如果现有数据违反约束依然会返回报错。
检查与验证双重作用下,具体的约束表现如下:
版权声明: 本文为 InfoQ 作者【YashanDB】的原创文章。
原文链接:【http://xie.infoq.cn/article/c54f722bf2a2e22468745782a】。文章转载请联系作者。
评论