如何实施对单表继承引用完整性?(How to enforce referential integri

2019-07-30 10:30发布

我读过一些的比尔Karwin的有关答复单表继承 ,并认为这种做法将有利于我正在考虑的设置:

Playlist
--------
id AUTO_INCREMENT
title

TeamPlaylist
------------
id REFERENCES Playlist.id
teamId REFERENCES Team.id

UserPlaylist
------------
id REFERENCES Playlist.id
userId REFERENCES User.id

PlaylistVideo
-------------
id
playlistId REFERENCES Playlist.id
videoId REFERENCES Video.id

所有CASCADE选项设置为DELETE哪些可以正常工作了,当Playlist被删除,但是,如果发生了什么UserTeam被删除?

即。 如果User被删除,在行UserPlaylist将被删除,但被引用的行PlaylistPlaylistVideo将保持不变。 我想过这个执行的TRIGGER AFTER DELETE ,但没有办法知道,如果删除请求出现,因为该方式Playlist被删除,或者如果User已被删除。

什么是执行在这种情况下完整性的最佳方式是什么?

编辑(所提供的ERD)

Answer 1:

在我看来,问题是,你的UserTeam表是应该有一个超表(如那些Party ),而不是播放表。

正如您所指出的那样,在播放列表做你的“表继承”试图找出删除的内容时,带有惩罚。 当您将继承到用户/组级别所有这些问题消失。

你可以看到这个答案约supertyping /亚型更详细 。

对不起,不提供代码,我不知道由心脏MySQL的句法。

基本概念是,超表格,您可以实现数据库的多态。 当你需要使用工作表链接到一组亚型中的任何一个 ,你只是使FK指向超代替了,这会自动获取你想要的“只是在时间的其中之一”的经营约束。 超类型具有与每个所述子类型的表的“一到零或一”的关系,并且每个亚型表使用在其PK从超类型表的PK相同的值。

在数据库中,通过具有只是一个Playlist与FK表Party (PartyID)你很容易地在不触发数据库级执行业务规则。



Answer 2:

你可以做的是落实在你的触发UsersTeam是执行每当行获取来自任一deleted表:

用户表:

DELIMITER $$
CREATE TRIGGER user_playlist_delete 
BEFORE DELETE ON User FOR EACH ROW
BEGIN
    DELETE a FROM Playlist a
    INNER JOIN UserPlaylist b ON a.id = b.id AND b.userId = OLD.id;
END$$
DELIMITER ;

团队表:

DELIMITER $$
CREATE TRIGGER team_playlist_delete 
BEFORE DELETE ON Team FOR EACH ROW
BEGIN
    DELETE a FROM Playlist a
    INNER JOIN TeamPlaylist b ON a.id = b.id AND b.teamId = OLD.id;
END$$
DELIMITER ;

什么这些触发器会做每一个记录从这些表中的一个被删除的时间,一个DELETE操作上会自动执行Playlists使用表id这是要被删除(通过内部连接)。

我测试了这一点,它的伟大工程。



Answer 3:

好吧,我看到你想要的这里......你想要做什么是运行像一个查询

DELETE FROM playlist
WHERE       id 
NOT IN      (
    SELECT  id
    FROM    UserPlayList
    UNION
    SELECT  id
    FROM    TeamPlayList
)

是行后,从用户或删除队



Answer 4:

通过赞恩边的答案是很明显的:superb.But我有这样做的不使用触发器,因为触发器有很多问题的想法。

您是否使用任何编程语言? 如果是的话,

使用一个单一的transaction ,使您的数据库auto commit false

写在播放列表和PlaylistVideo引用的行删除查询。 手动您必须通过使用参考ID(与WHERE条件)先写这个查询并运行它。

现在准备另一个查询你的主要任务,即删除用户,并在UserPlaylist的行会被自动删除(由于CASCADE DELETE选项)。现在运行你的第二个查询和commit

最后,让您的交易auto commit true

它成功地工作,希望它会有所帮助。



文章来源: How to enforce referential integrity on Single Table Inheritance?