如何删除行外键?

时间:2013-05-23 03:18:07

标签: sql h2 cascading-deletes

鉴于以下表格:

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标准是否对此问题有所说明?或者不同数据库的行为是否不同?

  4. 澄清:

    1. 公司/部门需要引用权限表而不是相反。这是因为permissions形成Closure Table(例如,用户拥有公司的权限,公司拥有部门的权限,因此用户有权访问部门)。由于层次关系跨越不同类型(即用户,公司,部门),因此权限表不能指向特定类型。因此,公司/部门必须参考许可,而不是相反。
    2. 说我想删除一个部门,我删除其权限是不够的,让CASCADE负责其余部分,因为它会删除部门的许可,部门和公司,但它'将忽略删除公司的许可。
    3. 在公司/部门被删除后,我无法使用触发器删除权限,因为H2在主要语句之外的单独数据库连接中运行触发器,并且两者请求在同一公司/部门行上写入锁定。第一个连接锁定我要删除的companies行。第二个连接(触发器)尝试删除与公司关联的permissions行,但ON CASCADE DELETE要求它也锁定公司。这是由于H2的限制造成的是一种解决方法。请参阅https://groups.google.com/d/msg/h2-database/B3xG488RBhI/DOsIMVmPBnAJ

1 个答案:

答案 0 :(得分:0)

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