草庐IT

php - 获取项目列表的更好方法 : cached serialized data vs database queries or other?

coder 2023-10-02 原文

我已经对文件中的缓存数据(serialize/unserialise vs json_encode/decodevar_exportigbonary)和 mysql 查询(优化、stored proceduresquery cache)进行了大量搜索,但此时此刻,我想知道优化如下具体案例的更好方法是什么。

提前抱歉:我想这是一个小答案的长话题,但有必要了解该项目。请原谅我糟糕的英语,这不是我的第一语言。

让我们假设我们有这个数据库关系。

数据库描述(括号内为估计记录数):

  • MODULE (10) : 是Item的类型,可以是文章,论坛话题,广告,新闻...
  • ITEM(百万):带有标题和一些文本的任何类型
  • CATEGORY (50) :项目类别(动物、政治、汽车、计算机...)
  • TAG(数十万):类别的标签(例如政治:国际、法国、巴拉克奥巴马……)
  • ITEM_TAG (outch):项目和标签关联

所以我们有几个关系,每个都是 ITEM 创建/更新时的记录器。

我已经使用以下示例将 ITEM 数据缓存在文件夹和文件中:

public function cacheItem()
{
    $req=mysql_query("SELECT id, title, content, id_mod, id_cat
            FROM ITEM
            WHERE ITEM.id='".$this->id."'")or die(mysql_error());
    if(mysql_num_rows($req)==1)
    {
        $this->itemData=mysql_fetch_array($req);
        $this->folder=floor($this->id/1000);//1000 items max per folder
        $this->itemUrl=$this->folder."/".$this->id.".txt";                      
        if(!file_exists($this->itemUrl))
        {
            touch($this->itemUrl);
        }
        file_put_contents($this->itemUrl,serialize($this->itemData),LOCK_EX);
    }
}

我通过 unserialize(file_get_contents($url)) 获取它们,这部分非常有效!

现在我希望优化 ITEM 列表以通过多个选项显示它们(例如,foreach 显示每个分页限制为 100:

  • 所有项目
  • 模块的项目
  • 类别的项目
  • 类别和模块的项目
  • TAG 的项目
  • TAG 和 CATEGORY 的项目
  • TAG、CATEGORY 和 MODULE 的项目

我已经知道如何在 SQL 中执行此操作并将结果放入缓存树中。

我的问题是,对于这些缓存文件,当创建/更新新的 ITEM 时,可能必须非常严格地刷新列表。

第一个问题:

那么如果同时创建/更新 ITEM(那些列表也是如此)会发生什么?

file_put_contents();LOCK_EX 是否会在从 file_get_contents(); 获取文件时完成他的工作?

第二个问题

我知道更多的 PHP 会工作,更少的 mySQL 会(否则),但是什么是更好(更快显示)的方式来做这些带有分页的列表,这些列表将每秒或更长时间显示,并且只被修改通过添加/更新新的项目?

  • 我的缓存系统(我不这么认为...)
  • mySQL 中的存储过程
  • 多个数据库服务器和/或多个文件服务器
  • 其他

非常感谢任何想法、示例和链接。

附言: 只是为了好玩,我可能会问“Facebook 如何”和“stackoverflow 如何”?

最佳答案

第一个问题:

使用 LOCK_EX,您的操作应该没问题。如果同时访问这些文件可能会被锁定,这肯定会减慢速度,但所有操作都应该正确完成。然而,这是一个很好的例子,说明为什么您不应该实现自己的缓存系统。

第二个问题:

MySQL 肯定会比您的缓存系统更快(除非您进行了一些认真的 wicket 编码,而不是使用 PHP)。像 MySQL 这样的数据库在优化性能方面做了大量工作。

我不认为 MySQL 中的存储过程会为您在上面提供的示例中提供比普通旧的 SELECT 查询任何真正的好处。

如果您在服务器集群上使用分片,则使用像 MongoDB 这样的 NoSQL 方法可以帮助您。这更难写,更多的服务器需要更多的钱。此外,从您的问题中不清楚是否可以选择迁移到不同的数据库系统。

如果您坚持使用 MySQL,那么实现负载平衡应用程序服务器可能比数据库服务器集群更容易。考虑到这一点,PHP 完成的更多工作优于 MySQL 完成的更多工作。不过,我不会采用这种方法,因为您只是为了一点点好处而放弃了很多。

简而言之,我建议您坚持使用简单的 SELECT 查询来获取您需要的内容。在单独的服务器上运行您的应用程序和数据库,并为您的数据库服务器使用更强大的服务器。

附言。 Facebook 为 PHP 编写了一个预编译器,使他们的代码运行得更快。在我看来,PHP 不是一种非常快的语言,您可以从 Python 或 Node.js 获得更好的结果。

Stackoverflow 将 ASP.NET MVC 与 MS SQL Server 结合使用。他们有一个强大的数据库服务器,显然他们宁愿在可能的地方使用数据库查询。他们还使用与数据库服务器分开的负载平衡应用服务器。

关于php - 获取项目列表的更好方法 : cached serialized data vs database queries or other?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14867774/

有关php - 获取项目列表的更好方法 : cached serialized data vs database queries or other?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  6. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  7. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  8. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

  9. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  10. ruby - RVM 使用列表[0] - 2

    是否有类似“RVMuse1”或“RVMuselist[0]”之类的内容而不是键入整个版本号。在任何时候,我们都会看到一个可能包含5个或更多ruby的列表,我们可以轻松地键入一个数字而不是X.X.X。这也有助于rvmgemset。 最佳答案 这在RVM2.0中是可能的=>https://docs.google.com/document/d/1xW9GeEpLOWPcddDg_hOPvK4oeLxJmU3Q5FiCNT7nTAc/edit?usp=sharing-知道链接的任何人都可以发表评论

随机推荐