4

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

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

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

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

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

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

但是,我正在阅读这篇文章,该文章认为由于锁定开销,没有必要进行物理删除。相反,作者建议使用这种方案:

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

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

4

2 回答 2

2

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

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

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

于 2010-12-16T06:44:22.283 回答
0

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

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

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

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

于 2010-12-16T06:33:04.100 回答