我读过一些的比尔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
被删除,但是,如果发生了什么User
或Team
被删除?
即。 如果User
被删除,在行UserPlaylist
将被删除,但被引用的行Playlist
和PlaylistVideo
将保持不变。 我想过这个执行的TRIGGER AFTER DELETE
,但没有办法知道,如果删除请求出现,因为该方式Playlist
被删除,或者如果User
已被删除。
什么是执行在这种情况下完整性的最佳方式是什么?
编辑(所提供的ERD)
在我看来,问题是,你的User
和Team
表是应该有一个超表(如那些Party
),而不是播放表。
正如您所指出的那样,在播放列表做你的“表继承”试图找出删除的内容时,带有惩罚。 当您将继承到用户/组级别所有这些问题消失。
你可以看到这个答案约supertyping /亚型更详细 。
对不起,不提供代码,我不知道由心脏MySQL的句法。
基本概念是,超表格,您可以实现数据库的多态。 当你需要使用工作表链接到一组亚型中的任何一个 ,你只是使FK指向超代替了,这会自动获取你想要的“只是在时间的其中之一”的经营约束。 超类型具有与每个所述子类型的表的“一到零或一”的关系,并且每个亚型表使用在其PK从超类型表的PK相同的值。
在数据库中,通过具有只是一个Playlist
与FK表Party (PartyID)
你很容易地在不触发数据库级执行业务规则。
你可以做的是落实在你的触发Users
和Team
是执行每当行获取来自任一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
这是要被删除(通过内部连接)。
我测试了这一点,它的伟大工程。
好吧,我看到你想要的这里......你想要做什么是运行像一个查询
DELETE FROM playlist
WHERE id
NOT IN (
SELECT id
FROM UserPlayList
UNION
SELECT id
FROM TeamPlayList
)
是行后,从用户或删除队
通过赞恩边的答案是很明显的:superb.But我有这样做的不使用触发器,因为触发器有很多问题的想法。
您是否使用任何编程语言? 如果是的话,
使用一个单一的transaction
,使您的数据库auto commit false
写在播放列表和PlaylistVideo引用的行删除查询。 手动您必须通过使用参考ID(与WHERE条件)先写这个查询并运行它。
现在准备另一个查询你的主要任务,即删除用户,并在UserPlaylist的行会被自动删除(由于CASCADE DELETE
选项)。现在运行你的第二个查询和commit
。
最后,让您的交易auto commit true
。
它成功地工作,希望它会有所帮助。