我正在计划一些多对多的表关系。从表中“删除”的最佳方法是什么?我应该将列标记为已删除吗?
Talbes
CREATE TABLE `comments`(
id INT NOT NULL,
comment TEXT,
status enum('active','inactive','deleted'), //Should this be added?
PRIMARY KEY(id)
);
CREATE TABLE `files`(
id INT NOT NULL
file_path VARCHAR(100),
status enum('active','inactive','deleted'), //Should this be added?
PRIMARY KEY (id)
);
CREATE TABLE `comments_files_xref`(
comment_id INT NOT NULL,
file_id INT NOT NULL,
PRIMARY KEY (comment_id,file_id)
);
我应该将status列设置为inactive并在select语句中放置WHERE table.status ='active'吗?我应该删除行吗?哪种表现最好?我总是可以运行一个cron来“清理”status =“deleted”行。
答案 0 :(得分:1)
这取决于几件事。你的问题并不完全清楚。根据您的评论,在您找到IsDeleted指标的位置,我将假设如果删除了Comment或File,那么您也想要删除CommentFile,听起来很奇怪,但我会继续使用它。
如果CommentFile中的行数很小,则对于Comment或File中的每一行,只需删除它们。
如果它很大,那么肯定,这是一个考虑因素,IsDeleted是一个好主意。然后是的,你需要一个在后台运行的cron作业,优先级较低,并删除WHERE IsDeleted = 1,批量为1,000。
但是将每个Select更改为包含WHERE IsDeleted = 0,都不会起作用。它将进行表扫描。为了克服这个问题(使(2)中的选择按计划工作),您需要添加一个索引,这会减慢插入和删除的速度。所以我会忘记(3)完全忘记(2);如果你有很多删除,运行两个cron作业,一个上升,一个下降。
更好的是,让清除工作无限循环运行,每天由cron启动一次。您可以同时运行两个以上:将表格除以PK范围到no_of_jobs。监控作业和真正的在线任务,通过在循环中插入一个微小的延迟(例如1或5秒)进行调整。这就是我们在大型OLTP银行系统中所做的工作。
答案 1 :(得分:0)
首先,设计您的数据库,使其符合您的应用程序的需求。如果您需要简单的“取消删除”或“查看已删除的记录”功能,请使用IsDeleted列并执行逻辑删除而不是物理删除。如果您不需要该功能,请不要因为担心从每个查询中删除逻辑删除的记录而使您的生活变得复杂。
然后,如果您确定在删除问题上存在某种性能问题,则可以在此时进行优化。除非你做了很多删除或拥有真正庞大的数据集,否则你很可能会遇到这个问题。
答案 2 :(得分:0)
为什么不将您计划删除的行卸载到同一个数据库或另一个仓库中的存档表中,然后从生产数据库中物理删除这些行?