【问题标题】:MySQL: What happens when the number of rows in a table gets out of hand? [closed]MySQL:当表中的行数失控时会发生什么? [关闭]
【发布时间】:2012-12-03 23:51:09
【问题描述】:

我需要在 Web 应用程序上实现消息传递系统。它由 PHP 和 MySQL 提供支持,允许注册用户互相发送消息。

所以我担心的是:在我让网站运行两年后,它会吸引成千上万的用户和几十个朋友,他们每个人都会在这段时间里互相发送数百万条消息?

IT 行业的“大佬”如何处理这些问题,例如 Facebook?当然,他们的消息不能全部放在一个表中(MySQL 或其他)......但即使在(一个)存档表中传输旧消息也不会永远有效。

我绝不会建立一个可以与 Facebook 相媲美的网站,但我仍然想要一个在一两年后不会出错的解决方案。

【问题讨论】:

  • 为什么我们从来没有听说过像 Facebook 这样的公司关闭数据中心?他们只会建造越来越多越来越多...
  • mysql 可以处理几个 TB 的表(取决于操作系统)所以不用担心
  • 当您拥有足够大的数据时,您肯定还会拥有训练有素且合格的 DBA 来帮助您找出未来的最佳解决方案,无论是分片还是复制、非规范化或切换到不同的数据库。

标签: php mysql limit rows archive


【解决方案1】:

“大男孩”使用分片。在最基本的层面上,这会将以字母“A”开头的用户放在数据库服务器“A”上,“B”放在“B”上,等等。但要明确的是,“大男孩”有数十亿消息,而不是数百万。 MySQL 应该可以处理数亿条记录。如果设计不当,您的查询可能会变慢。

我曾经创建了一个基于 MySQL 的消息传递系统,该系统每月处理大约 5000 万条消息。我们只保留了过去 3 个月的“活跃”状态,任何较旧的内容都位于访问速度较慢的存档区域中。

老实说,如果你能设计出一个 2 年后不需要保姆的系统,那你就太棒了!

【讨论】:

    【解决方案2】:

    搜索 SQL BIGINT 的最大值。几年前,当我在 32 位机器上编写这个脚本时,它曾经溢出。现在问题已经小多了!

    http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html

    http://www.laprbass.com/RAY_integer_overflow.php

    <?php // RAY_integer_overflow.php
    error_reporting(E_ALL);
    echo "<pre>\n";
    
    // CONNECTION AND SELECTION VARIABLES FOR THE DATABASE
    $db_host = "localhost"; // PROBABLY THIS IS OK
    $db_name = "??";        // GET THESE FROM YOUR HOSTING COMPANY
    $db_user = "??";
    $db_word = "??";
    
    // OPEN A CONNECTION TO THE DATA BASE SERVER
    // MAN PAGE: http://us2.php.net/manual/en/function.mysql-connect.php
    if (!$dbcx = mysql_connect("$db_host", "$db_user", "$db_word"))
    {
       $errmsg = mysql_errno() . ' ' . mysql_error();
       echo "<br/>NO DB CONNECTION: ";
       echo "<br/> $errmsg <br/>";
    }
    
    // SELECT THE MYSQL DATA BASE
    // MAN PAGE: http://us2.php.net/manual/en/function.mysql-select-db.php
    if (!$db_sel = mysql_select_db($db_name, $dbcx))
    {
       $errmsg = mysql_errno() . ' ' . mysql_error();
       echo "<br/>NO DB SELECTION: ";
       echo "<br/> $errmsg <br/>";
       die('NO DATA BASE');
    }
    
    // CREATE A TABLE AND ALTER IT TO A HIGH INDEX NUMBER
    $sql = "CREATE TEMPORARY TABLE noise ( id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY ) ENGINE=MEMORY";
    if (!$res = mysql_query($sql)) die(mysql_error());
    
    $sql = "ALTER TABLE noise AUTO_INCREMENT = 2147483646";
    if (!$res = mysql_query($sql)) die(mysql_error());
    
    
    // INSERT DATA TO ADD TO THE AUTO_INCREMENT INDEX
    $kount = 0;
    while ($kount < 15)
    {
       $sql = "INSERT INTO noise () VALUES ()";
       if (!$res = mysql_query($sql)) die(mysql_error());
       $nid = mysql_insert_id($dbcx);
       var_dump($nid);
       $kount++;
    }
    

    根据我的粗略计算,如果您以每秒 1,000 条的速度聚合消息,并且您将 UNSIGNED BIGINT 用于您的 AUTO_INCREMENT 键,那么您将在大约 570,000,000 年后经历一次溢出。因此,或多或少地,如果您以每秒 1,000,000,000 条的速度收集消息,您将在更短的时间内遇到问题 - 可能从现在起大约 570 年。但好消息是,如果你以每秒 100,000 条的速度收集消息,VC 社区就会向你砸钱!

    【讨论】:

    • 注意! PHP 的未来版本将弃用和删除mysql_ 系列函数。现在是switch your example code to PDOmysqli 的好时机。
    • @Charles mysql_ 函数已正式弃用。
    • @njk,从 5.5 开始,是的,因此是“未来版本”的措辞。
    【解决方案3】:

    在第一步中对表进行分区(根据您的设计,根据日期、用户 ID、区域或任何其他基础)。我相信您可以长期使用此解决方案。下一步将分片您的消息系统。即使在此更改之后,您也可以像 facebook 这样选择 HBase。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-10
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-11
      相关资源
      最近更新 更多