1

给定下表:

create table permissions(id identity);
create table companies(id identity, 
    permission_id bigint not null, 
    foreign key(permission_id) references permissions(id) on delete cascade);
create table departments(id identity, 
    company_id bigint not null, 
    permission_id bigint not null, 
    foreign key(company_id) references companies(id), 
    foreign key(permission_id) references permissions(id) on delete cascade);

删除部门时,我希望以下语句自动执行:

  • departments行已删除
  • permissions与部门行关联的行被删除
  • companies与部门行关联的行被删除
  • permissions与公司关联的行(上一点)被删除

问题:

  1. 如果我在所有外键上使用READ_COMMITTED事务隔离ON CASCADE DELETE,是否将行作为单个原子语句删除?或者它们是否作为容易受到READ_COMMITTED异常影响的单独删除语句执行?
  2. 当公司/部门被删除时(如果可能,原子地),如何指示数据库删除公司/部门权限?
  3. SQL 标准对这个问题有任何说明吗?或者不同数据库的行为是否不同?

澄清:

  1. 公司/部门需要参考权限表,而不是相反。这是因为permissions形成了一个闭包表(例如,用户对公司有权限,公司对部门有权限,因此用户对部门有权限)。因为层次关系跨越不同类型(即用户、公司、部门),权限表不能指向特定类型。因此,公司/部门必须引用许可,而不是相反。
  2. 假设我要删除一个部门,我删除它的权限是不够CASCADE的,剩下的交给我处理,因为它会删除部门的权限,部门和公司,但它会忽略删除公司的权限。
  3. 在删除公司/部门后,我无法使用触发器删除权限,因为 H2 在与主语句不同的数据库连接中运行触发器,并且两者请求对同一公司/部门行进行写锁定。第一个连接锁定了companies我要删除的行。第二个连接(触发器)尝试删除permissions与公司关联的行,但也ON CASCADE DELETE要求它锁定公司。这是由 H2 的限制引起的,对此有解决方法。请参阅https://groups.google.com/d/msg/h2-database/B3xG488RBhI/DOsIMVmPBnAJ
4

1 回答 1

0

它在大多数数据库中都是原子的,除了带有 MyISAM 和 MS Access 的 mysql,通常你可以用触发器做你想做的事,但这很奇怪,因为通常与我们想要的相反,我的意思是当一个权限被删除时拥有该权限的部门也被删除

于 2013-05-23T03:35:37.093 回答