将数据保存到文件和。将其保存到 MySQL DB

Posted

技术标签:

【中文标题】将数据保存到文件和。将其保存到 MySQL DB【英文标题】:Saving data to a file vs. saving it to MySQL DB 【发布时间】:2010-11-30 12:09:45 【问题描述】:

使用 php 脚本,当有人在我的页面上时,我需要每 5 秒更新一次数字。因此,假设我有 300 名访问者,每个访问者在页面上花费大约 1 分钟,并且他们停留在页面上的每 5 秒,数字就会改变......每分钟总共有 3600 次更改。我更愿意更新我的 mysql 数据库中的数字,除非我不确定拥有这么多 MySQL 连接(只是为了改变一个数字)是否效率太低,而我可以只更改文件中的数字。

P.S.:我不知道天气 3600 连接/分钟是不是一个很高的数字,但是考虑到更多的访问者,一般情况下如何处理。最有效的方法是什么?

【问题讨论】:

澄清一下...每分钟 3,600 次更改会发生在 same 文件上吗? 【参考方案1】:

每分钟对同一个文件进行 3,600 次读取和写入是毫无疑问的。这很复杂(您需要非常小心文件锁定),性能会很差,而且您的数据迟早会损坏。

像 MySQL 这样的 DBMS 是为并发访问而设计的。如果他们无法应付您的负载,文件也不会做得更好。

【讨论】:

非常感谢您的回答...顺便说一句。你知道 MySQL 连接数的实际限制是什么,它取决于什么(除了 CPU 和 RAM)?最大值是多少。 MySQL DB 可以处理的连接数? 除了 CPU 和 RAM?剩下的不多了:磁盘性能和带宽 :) 但我认为您将每分钟的连接数与 同时 连接数混淆了;不一样。 对不起 :) 同时连接正是我的想法 :)【参考方案2】:

如果用户数量增加,它最终会失败,但性能取决于您的服务器设置和与此更新相关的其他任务。

您可以做一个小测试并打开 300 个到您的数据库的持久连接,并在几分钟内启动尽可能多的查询。

如果您不需要它是事务性的(执行查询的顺序并不重要),那么我建议您使用 memcached(如果您需要将内容保存在磁盘上,则使用 redis)来代替

【讨论】:

是否有程序(或 PHP 脚本)可以提供我需要的统计信息(或运行测试本身)? 只需设置计数器并使用 ab cyberciti.biz/tips/… 运行测试【参考方案3】:

如果你保存到文件,你必须解决并发问题(除了当前的读/写进程之外的所有进程都必须等待)。 db 为您解决了这个问题。为了获得更好的性能,您可以使用 memcached。

也许您可以通过另一种方式(例如,节省当前时间并减去用户下次做某事时)来“为每个用户每 5 秒做一次”。这取决于您的实际问题。

【讨论】:

【参考方案4】:

甚至不要考虑尝试用文件来处理这个问题——除非你构建一个锁队列管理器,否则它不会工作——如果你遇到了所有这些麻烦,你还不如使用守护进程来管理值,而不仅仅是队列锁。

使用 DBMS 是最简单的方法。

要获得更高效但更深奥的方法,请编写一个单线程套接字服务器守护程序并让客户端连接到该守护程序。 (lib here 用于处理套接字,PEAR class 用于将 PHP 作为守护程序运行)

【讨论】:

【参考方案5】:

文件不是事务性的,您不想丢失计数,所以数据库是要走的路

memcached 的 inc 命令比数据库更快,是我认为一个非常快速的视图计数设置的基础

如果您使用每小时说一个键并切换,那么当页面视图发生时 inc page:time 发生,您可以让后台进程收集过去一小时的计数并在内存缓存失败时将它们插入数据库您可能会丢失该小时的计数,但您不会重复计数或错过任何计数,并且保持每个周期的计数会提供有趣的统计数据

【讨论】:

【参考方案6】:

使用专用临时文件肯定是您可以拥有的最有效的磁盘访问。但是,如果您的服务器使用多个线程或进程,您将不会受到对文件的并发访问的保护。如果您要做的是为每个用户更新 1 个数字,那么使用 $_SESSION 子变量就可以了,我相信它存储在内存中,所以它应该非常有效。然后,您可以轻松地将每个用户每 5 分钟将此数字存储到您的数据库中

【讨论】:

"如果您的服务器使用多个线程或进程" - 您知道在进程内运行 PHP 的单线程网络服务器吗?我没有。

以上是关于将数据保存到文件和。将其保存到 MySQL DB的主要内容,如果未能解决你的问题,请参考以下文章

如何从 MySQL 数据库的内容中即时创建 Access DB 并在本地保存

自动提交复选框以保存到 MySQL

将python中的值保存到mysql db

如何在 Android 上将数据保存到文本文件?

将数据从耳语保存到mysql

无法将数据保存到 mysql db,在 gradle 项目中,bean 名称“goal”的 BindingResult 和普通目标对象都不能用作请求属性