选择一种方法而不是另一种方法从 Mysql 获取数据的复杂性

Posted

技术标签:

【中文标题】选择一种方法而不是另一种方法从 Mysql 获取数据的复杂性【英文标题】:Complexity in choosing one method over another for fetching data from Mysql 【发布时间】:2011-10-23 19:16:50 【问题描述】:

我正在做一个基于 phpmysql、Apache 的项目。

我有一个名为通知的模块,就像 FACEBOOK 中可用的通知一样,为此我有 3 种方法

要么 我将每个更新插入到一个表中,计算需要通知这些更新的用户数量,即如果假设类别 B 有一些更新并且此类别 B 包含 100 个用户,那么我将为相应的用户插入 100 行比如通知表。

第二种方式

我可以做的只是在表中插入一个特定的类别条目,然后对每个护理 ID 进行繁重的 JOIN 查询,以从多个表中获取所有记录以获取记录。

第三种方式

我在每次更新时都使用触发器,以便它可以用于通知用户。

我相信这三种方式在某些时候都是有问题的。

现在任何人都可以提出更好的想法或其中一个是更好的选择吗?

我担心网站的性能,因为它会有大量条目

谢谢

【问题讨论】:

类别与用户的关系是一对一还是多对多? 能否请您添加您将发行的common queries 和您的schema。我所说的常见查询的意思是 1. 查找必须向其发送此通知的所有用户。 2. 查找用户的pending 通知。 3.查找notified用户的通知。等等。这可以更好地了解您正在尝试做什么。当您说批量条目时,是指用户数量吗?谢谢。 【参考方案1】:

这比我最初想的要复杂一些:)

应用/用户行为如何?我们什么时候应该做最多的工作?是插入数据的时候,还是我们获取数据的时候。

我将不得不对最常见的操作做出假设。我会假设获取数据会更常见一些,因为许多用户会看到未读消息的通知,但只有一个“插入”新消息?

因此,我会将工作放在插入新通知上,但当用户开始涌向您的应用时,结果可能会很糟糕。

但我认为模型需要在任何优化之前设置,这更重要。稍后可以通过使用denormalisation、调度等来管理优化。我不会真正接触触发器,恕我直言,它们有点时髦。

我也会另辟蹊径。

用户写了一条新消息

插入消息

更新当时更新的 user_category(有很多)类别

UPDATE user_category SET last_changed = 'NOW()' where category_id = ?;

如何查找用户未读消息

选择自上次用户查看后已更新的类别(脏?)。 从那些不在“user_message_noticed”中的类别中选择所有消息(见下文)。

用户已阅读消息

在耦合消息和用户的 *user_message_noticed* 模式中插入一行。类别 id 在那里,因此我们可以在没有额外连接的情况下更快地完成上述操作。

关于从该类别阅读的所有消息 - 使用用户阅读所有消息的日期更新 *user_category™(有很多很多)。

但有时,您无法真正摆脱实际工作。

【讨论】:

【参考方案2】:

MySQL 中的触发器支持充其量是粗制滥造的,所以我不会朝那个方向努力,尽管这可能是一个很好的方法。

最简单的方法如下:每次登录/注销时,从“在线用户”.id 中插入/删除用户,然后使用前端(无论如何都要搞砸)不时询问以知道他知道哪些 id 在表中。

Join 除了在 mysql 中相对不太聪明外,在大表上即使有索引也会很慢。

触发器,同样如此,然后,您会要求触发器做什么?推送到此人已登录的所有内容?推给有兴趣的人?这意味着又一次加入,即性能下降。

通知表?无缘无故地巨大而缓慢(即 100 个插入而不是一个 where 查询 ..meh)。

【讨论】:

以上是关于选择一种方法而不是另一种方法从 Mysql 获取数据的复杂性的主要内容,如果未能解决你的问题,请参考以下文章

如何以另一种方法从列表中获取一个结果?

有没有一种方法可以使用 android-sqlite 游标从列数未知的表中选择 *

为啥你可以在函数中使用另一种方法而不是赋值运算符来更改 Ruby 中局部变量的值?

如何将数据从 Web 服务中的一种方法发送到另一种方法

如何从另一种方法访问 StorageFile

还有另一种方法可以从 Fabric JS 获取 JSON 中存在的 Circle 对象吗?