2011-06-11 38 views
3

我正在为我的PHP应用程序开发一个简单的AJAX聊天附加组件,因此我可以为我的用户提供实时支持。我目前正在使用一个存储正在聊天的人的文本,时间戳和user_id的MySQL数据库。我不得不考虑如何优化我的聊天,并开始考虑删除对SQL数据库的需求。文件与数据库在聊天应用程序中的存储效率

我的问题是,使用fwrite()将额外的数据附加到PHP文件以存储相同的信息而不是创建SQL连接来检索聊天的新帖子会更高效吗?我知道我会如何有效地完成这项工作,我只是想弄清楚哪种方法更有效率。

我在SQLite中看起来也有点儿;这会比使用MySQL数据库更好吗?

+0

关于使用SQLite是什么(在服务器带宽)连接? – 2011-06-11 07:19:48

+0

可能将聊天保存在数组中,并且当聊天关闭时,将它写入文本文件 – 2011-06-11 07:20:51

+0

您可以以某种方式连接池吗?这可能会提高你的速度。 – 2011-06-11 07:21:25

回答

4

存在数据库管理系统(DBMS)是因为它看起来不像存储和访问数据那样容易。

将数据存储在文件中意味着访问并发问题。当文件变大时,你将不得不面对重要的内存使用,或者编写大量的代码来加载你所需要的。像过滤(SQL WHERE子句)或更新行这样的基本操作也很难。顺便说一句,改变数据结构承诺容易出错。我更简单的话:你将不得不写很多代码并面对很多错误。

国际海事组织,不使用任何种类的数据库管理系统正在重新创建轮子。然而选择正确的一个很重要。

0

如果您删除或存档旧的对话,MySQL将是不错的选择。不要忘记在日期和用户或会话ID上放置索引,以便快速检索它们。

+0

我通过Cron运行日常维护以删除超过24小时的帖子。我唯一的问题是,如果数以千计的用户使用任何形式的聊天(我只有一个服务器和数据库),那么我需要尽可能高效地确保事情顺利进行。这就是为什么我试图找出最佳的行动方式。这次聊天也会在我的应用中的其他地方进行,因此用户可以互相交谈。 – Phillip 2011-06-11 07:27:54

+0

我相信mysql可以处理它,但是在开始编码之前使用MyISAM并做一个压力测试。 – 2011-06-11 07:30:32

0

我会坚持使用MySQL,因为它比一个简单的文件更适合从Web应用程序进行多路访问。

首先,使用持久连接。

在使用它时,如果您尚未使用PDO,我会建议您使用。 (持久连接的PDO选项为PDO :: ATTR_PERSISTENT => true)

注意:PHP中的默认设置是简单地模拟预准备语句。您希望它成为TRUE预准备语句,因此将PDO :: ATTR_EMULATE_PREPARES设置为0.(http://bugs.php.net/bug.php?id=54638)

另外:Prepared语句不会使用MySQL缓存在5.1.17之前的版本中,并且不会缓存5.1.21之前的变量准备语句,所以确保你有最新版本的MySQL。

PDO不仅提供了潜在的性能提升。你应该看看,如果你还没有。 有关PDO的更多信息,请访问:http://ca2.php.net/manual/en/book.pdo.php

0

由于其他人已经介绍了MySQL vs Text,我想给你一个替代方案。

这些类型的应用程序非常适用于像MongoDB这样的noSQL解决方案。由于您最有可能在一段时间内轮询服务器,因此具有非常快的读取能力是一个好主意。

您也可以使用类似Node.JS的东西将它们连接在一起。

1

尽管这是一个古老的问题,但我还是把戒指扔在戒指里。对于速度,可靠性和易用性来说,数据库是一个明显的容易选择......有很多人忽略了一个主要的警告,那就是大多数共享主机(最常见的网络托管形式)只允许15或者所以一次连接,即使VPS通常只允许100-200,专用500或更多。这意味着如果你有(n)个用户每秒汇集一次,那么这些连接将快速消失,如果你还运行任何类型的CMS,速度甚至会更快。在VPS上开发自己的聊天室代码时,我自己也面临着这些问题。

到目前为止我的方法就是这样。

  • 确保传递lastMessageReceived变量来限制响应。
  • 如果公共聊天室通过时间戳过滤器以及上述
  • 如果可能的话尽可能使用数据库缓存引擎(如MySQLnd),并启用查询缓存并将TTL设置为您的池化速率。
  • 不要让你的游泳池速度变得疯狂1-2秒的间隔可能看起来很整洁,但它会杀死你的连接数。将其降低到5秒甚至更多不会真的产生巨大的差异,用户可能不会注意到,并且您的服务器负载会轻得多。甚至考虑在高负荷期间自身产生的变化汇集率。
  • 编写您的ajax使用超时而不是时间间隔为其池并将超时调用放置在ajax成功回调中,这可以防止请求在峰值ussage期间堆叠起来。
  • 而最大的一个,如果使用与许多用户共享的聊天室,编写自己的代码来将SQL查询缓存到json文件并将其提供给ajax请求,并编写一些自定义TTL代码来检查其年龄和重新 - 在请求期间根据需要填充它,如果您的主机允许,CRON会很棒。年龄检查文件并重定向AJAX请求是一个更高级别的功能,与查询数据库相比,它的服务器开销非常小。并且不要在PHP中解析文件来筛选旧邮件,将第一条邮件中的第一条邮件存储在文件名中,如chat_243.json,并将其保存为已格式化的json,然后在请求进入php与lastMessageReceived = 243。由于这会创建多个文件,因此您需要一个清理超过(m)分钟的文件的功能,但这对于服务器来说也是轻量级的工作。

也有像DB引擎专为聊天和插座(node.js的)的选项,但那些需要更多的服务器的调整比典型的托管帐户允许,我的目的,我一直在写记住我的聊天室保管它可能会在某个时候被部署到共享服务器上。

这里是我目前使用的代码,它已几乎让我到我的聊天扩大到无限数量的

$cacheFile = 'cache/chat_'.$_GET['last'].'.json'; 

if (file_exists($cacheFile) && filemtime($cacheFile) + QUERY_REFRESH_RATE > time()) 
{ 
    readfile($cacheFile); 
} else { 
    require_once("../../../../wp-load.php"); 
    $timestampMin = gmdate("Y-m-d H:i:s", (time() - 7200)); 

    $sql= "/*qc=on*/" . "SELECT * FROM ". DB_TABLE ."chat_posts WHERE ID > ". $_GET['last'] . " AND timestamp > '".$timestampMin."' ORDER BY ID;"; 
    $posts = $wpdb->get_results($sql); 

    $json = json_encode($posts); 
    echo $json; 
    file_put_contents($cacheFile,$json); 
} 
+0

听起来很有趣,但可悲的是我没有完全得到你所建议的..所以我会存储一个新的消息到db和一个json编码的平面文件,所以我的ajax只是得到这个平面文件,而不是查询数据库? – Can 2016-03-18 18:59:16

+0

您只会将它们存储在数据库中,平面文件会根据年龄进行更新。我上面发布了示例代码。 – Wobbles 2016-03-18 23:16:18