JET 数据库/数据完整性
JET(及其主要应用程序包装器 Microsoft Access)通常因数据完整性差而受到指责,但这通常是因为数据库的数据完整性功能很少或根本没有得到适当使用。
JET 数据库支持关系数据库所期望的许多标准数据完整性功能,包括约束、事务和锁定。这种支持随着时间的推移而发展,只有 JET 4.0 支持某些功能。
在多用户环境中使用 JET 数据库也存在一些锁定和缓冲问题,特别是在局域网 (LAN) 上。然而,此类问题可能是另一章的主题。
主键有助于为表定义一组列,这些列可用于唯一标识每一行。在构成主键的列中,任何两行都不能具有相同的值,数据库通过拒绝在主键列中已存在具有这些值的行的同时插入行来强制执行此约束。
JET 支持唯一索引和唯一约束,它们是微妙不同的概念,但本质上实现了相同的功能。唯一索引是一个索引,该索引的列不能具有重复的值,而唯一约束是一个数据完整性规则,它阻止插入具有相同值的行的约束中列出的列。两者都可以用来实现逻辑数据模型概念中的候选键。
JET 引擎通过创建唯一索引来实现唯一约束的概念。唯一约束可以在Create Table
语句中添加到表中,或者通过Alter Table
语句添加。
JET 支持外键约束,允许在数据库级别强制执行实体关系数据建模规则。外键约束阻止在相关表中不存在对应行的行被插入,并且还阻止在相关表具有引用它们的依赖行时删除行。
JET 引擎会自动在构成外键的列上创建索引。
外键约束必须引用所引用表上的主键、唯一约束或唯一索引中的所有列。下面的代码显示了一个引用另一个表上的唯一约束(例如候选键)的外键。
Create Table F3 (
id int identity(1, 1) not null,
a int not null,
b varchar(20) not null,
c varchar(20) not null,
Constraint F3_pk Primary Key (id),
Constraint F3_uc Unique (a, b)
)
go
Create Table F4 (
i int not null,
a int not null,
b varchar(20) not null,
Constraint F4_pk Primary Key (i),
Constraint F4_fk1 Foreign Key (a, b) References F3 (a, b)
)
go
JET 4.0 引入了对外键的级联更新和删除。当使用Update Cascade
创建外键时,如果所引用列发生更改,则外键会更新。Delete Cascade
会导致在删除所引用行时删除引用行,而Delete Set Null
会将外键设置为 Null(如果删除所引用行)。
Create Table F5 (
i int not null,
a int not null,
b varchar(20) not null,
Constraint F5_pk Primary Key (i),
Constraint F5_fk1 Foreign Key (a, b) References F3 (a, b)
On Update Cascade On Delete Set Null
)
go
JET 4.0 引入了检查约束,这些约束在数据库的数据完整性中应用了额外的逻辑。检查约束是一个表达式,它进一步约束了列中允许的值。表达式可以是简单的值边界验证,也可以包含引用其他表中值的子查询。
检查约束不仅可以用于验证输入值。以下示例展示了检查约束如何确保表只包含一行。
Create Table Singleton (
ID Char(1) Not Null,
a varchar(20),
...
Constraint Singleton_PK Primary Key (ID),
Constraint Singleton_One_Row check(ID = 'A')
)
go
从 JET 4.0 开始,JET 支持多个语句的事务,使开发人员能够编写健壮的代码来更新数据库,而不会影响逻辑一致性,例如,允许创建一半的发票或更新一半的客户记录。因此,在已声明事务中,语句将一起成功或一起失败。
事务必须通过发出Begin Transaction
语句显式创建。后续语句在发出Commit
或Commit Transaction
语句之前不会提交到数据库。如果发出Rollback
或Rollback Transaction
语句,则自事务开始以来的所有语句都将失败,即这些语句都不会提交到数据库。
Begin Transaction
go
Insert Into U1 (a, b, c) Values (1, 'First', 'Row')
go
Rollback Transaction
go
Select * From U1
go
(0 row(s) returned)
当使用 Microsoft 的 ADO 数据库组件时,事务通常通过这些对象上的 BeginTrans / CommitTrans / RollbackTrans 方法管理。但是,它们也可以通过语句执行轻松实现,如上所示。
JET 支持对数据库进行读和写锁定,可以通过独占访问或共享访问来实现。锁定可以在行级别、页面级别或数据库级别设置。
从 JET 4.0 开始,当锁定的行数达到阈值时,行级锁定将自动提升到页面级或表级。此阈值在 Windows 注册表项PagesLockedToTableLock
中设置,该项位于密钥HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Jet 4.0
下
锁定可以通过设置数据库连接上的隔离级别来配置。对于 ADO,这是通过Connection
对象上的IsolationLevel
属性来完成的。