【问题标题】:mysql tables and deleting strategiesmysql表和删除策略
【发布时间】:2011-05-26 08:56:02
【问题描述】:

我正在开发一个社交网络,比如 Facebook 的一个子集。我认为这意味着应用程序的读取量将大于写入量(即 SELECTS 比 INSERTS、UPDATES 或 DELETES 多)

我打算将 MySQL 用于数据库,使用 MyISAM。数据库中的每个表都会包含以下三个字段:

  • CREATED - 包含记录创建时间的日期字段
  • UPDATED - 包含修改记录时间的日期字段
  • ROWSTATUS - 一个 CHAR(1) 字段,其中包含一个字符标志,用于显示记录是活动、非活动还是已删除(分别使用值“A”、ID)。

通过 PHP 包装类,我们确保所有 SELECT 查询都包含 ROWSTATUS,UPDATE 查询也更新 UPDATED 列,INSERT 查询更新 CREATED 列。

我打算不实际删除任何记录,而是选择将记录 ROWSTATUS 字段更新为 D 以显示它已被删除(即软删除)。

我们有一个 SQL 程序,它会在 10 天后物理删除已删除的数据。

但是,我正在经历this article,它认为由于锁定开销,没有必要进行物理删除。相反,作者建议使用这种方案:

SELECT e.eventid,e.title
    FROM events e
   WHERE NOT EXISTS
    (SELECT * FROM event_deletes ed WHERE ed.eventid = e.eventid);

我想知道我的方案与这个提议的机制相比如何,哪个更好?我自己无法得出任何明确的答案。

【问题讨论】:

  • 对这个建议持保留态度。自那篇文章发表以来的近 7 年里发生了很多变化。
  • 您计划使用 MyISAM 而不是 InnoDB 有什么原因吗?
  • @AgentConundrum ...我们已经在使用 MyISAM,我正在考虑迁移到 InnoDB。只想调查利弊
  • 老实说,MyISAM 唯一想到的“专业人士”就是它的全文搜索。如果您不需要它,那么我会选择 InnoDB。即使您确实需要它,您最好还是使用 Sphinx 之类的东西作为您的 FTS。
  • 但是我们有列 VARCHAR 或 TEXT 类型并且我们执行查询 [colname like '%USER_SEARCH_QUERY%']。推荐的做法是什么?

标签: mysql myisam sql-delete overhead


【解决方案1】:

正如@Pentium10 所说,您的计划本质上没有任何问题。这实际上是一种相当标准的方法。

问题在于,如果您使用 MyISAM,您的 UPDATE 将导致整个表在查询运行时锁定。这引入了瓶颈,因为您一次只能更新或删除一条记录。

除非您有使用 MyISAM 的理由,否则我建议您切换到 InnoDB 作为您的数据库引擎。 InnoDB 使用行级锁定,因此您的 UPDATE 查询不会阻塞其他 UPDATE。它还具有其他一些不错的功能,例如支持事务和引用完整性约束。

【讨论】:

  • 是的..我认为这是有道理的..我错了。我们应该选择 InnoDB 以充分利用我们的数据库设计。指参照完整性。好吧,我们根本不使用外键。我们尝试通过我们的代码来管理所有的事情。
【解决方案2】:

与那篇文章相比,我在这里看到的唯一问题是,您只处理 DELETE 调用的锁。

您应该知道 UPDATE 和 DELETE 语句总是需要对 MyISAM 表发出排他锁。

这就是本文建议使用 INSERT 而不是 UPDATE 行状态的原因。你应该按照文章说的去。创建一个专用表来存储已删除的 id,并在 selects 上使用推荐的连接来检索未删除的记录。这样,在最终用户的删除操作中,您只需插入表中,不会导致表上的 UPDATE 锁定。如果您为两个表都添加了正确的键,则连接将仅在索引上完成,因为它在 SELECT 上会很快。

如果存储更新时间,也会引入开销。你应该放弃这个想法,因为它没有用,而且你不会用它来判断记录何时更新。

【讨论】:

  • 是的。感谢您的回答。基本上我错了。指 UPDATED 列。实际上我们也用它来查找一些信息;特别是在报告模块中
猜你喜欢
  • 1970-01-01
  • 2017-07-07
  • 1970-01-01
  • 1970-01-01
  • 2016-06-30
  • 1970-01-01
  • 2018-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多