Ms-Access-365

強制執行 1 個或多個關係

  • June 21, 2016

在下面的er圖中(不是我的),

在此處輸入圖像描述

一個班級可以通過一個標準的聯結表有許多教師。有沒有一種方法可以使用約束來設計 Instructors/Classes 表,以確保一個 Class 必須至少有一個 Instructor?即 1 個或多個而不是 0 個或多個?所以給定 Classes.class_id=1,必須有一個 Instructors_Classes(class_id=1,instructor_id=?) 或者這是你只是使用觸發器來強制執行的東西?

作為輔助,任何人都可以提出一個好的方法來確定一個,並且只有一個講師作為一個班級的主要講師?目前我添加了一個欄位 Instructors_Classes.IsPrimary (number) 並在 (class_id, IsPrimary) 上應用了唯一約束和 IsPrimary=Null OR 1 的驗證約束,因此每個班級只有 1 位教師可以有值 1。然後,當我想獲取所有類的列表時,我可以加入 Instructors_Classes.class_id WHERE IsPrimary=1 以便獲得該類的 Instructor 的單個值。這只是感覺有點不對,但我不是數據庫人,所以我不知道是否有更傳統的方法。我想添加一個 Classes.instructor_id 欄位,但無法弄清楚如何強制它與 Instructors_Classes 表之間的連結。

真正的“一個類必須至少有一個 Instructor”約束只能在事務送出時檢查,因為首先我們需要插入 aClasses並且只有在至少一個Classes存在之後我們才能在Instructors_Classes. 不,目前大多數 DBMS 都沒有實現這樣的功能。每個語句檢查約束,此檢查不會推遲到事務送出。Postrgesql 可以推遲 FK 和其他一些約束直到送出(感謝,ypercubeᵀᴹ)。

您可以實施刪除觸發器,Instructors_Classes以防止刪除班級的最後一位教師。

但是您的第二個“班級主要講師”要求會有所幫助。添加Classes.PrimaryInstructor 引用Instructors_Classes可為空的。設置值後 Classes.PrimaryInstructor,此 FK 將確保(通過適當的 ON DELETE/UPDATE 操作)至少保留課程的主要講師。

編輯

準確地說,FK 以上應該是複合的,還包括ClassesPK ,

create table Classes (
...
constraint FK_prim_instr foreign key (class_id, primary_instructor) references class_instructors(class_id,instructor_id)
...
);

編輯 2

範例腳本

-- MS Sql Server 2014 

create table classes ( 
   class_id int not null primary key
   , primary_instructor int null
);

create table class_instructors(
   class_id int not null
   , instructor_id int not null 
   , constraint PK_cl_instr 
     primary key (class_id, instructor_id)
   , constraint FK_class_instr 
     foreign key (class_id)
     references classes (class_id)
);
go
alter table classes 
add constraint FK_Prim_instr 
     foreign key (class_id, primary_instructor)
     references class_instructors(class_id, instructor_id)

insert classes (class_id) 
values (1);

insert class_instructors (class_id,instructor_id) 
values (1, 10),(1,20);

update classes 
set primary_instructor = 20
where class_id = 1;

select * from classes;
select * from class_instructors ;

-- this will fail
insert class_instructors (class_id,instructor_id) 
values (2,10);

-- this will fail too
update classes 
set primary_instructor = 30
where class_id = 1;

引用自:https://dba.stackexchange.com/questions/141760