【问题标题】:Best way to store unchanging data存储不变数据的最佳方式
【发布时间】:2013-08-04 15:10:20
【问题描述】:

在开发游戏时,我经常使用 MySQL 数据库。

但最近我将很多 SELECT 结果放在 Memcache 中,因为它们不太可能改变。

这让我想知道,仅仅拥有一个定义数据数组的 PHP 文件不是更好吗?当然,这意味着我必须加载整个数组才能访问一行,但我相信与不必等待 MySQL 节省的时间相比,这微不足道。

我在这条思路上是否正确?我应该将我不变的游戏数据(例如角色基础统计、兼容性图表、项目数据等)移动到 PHP 文件吗?还是我应该继续使用 MySQL+Memcache?

哪个更好,为什么?

【问题讨论】:

  • 为什么使用 PHP 文件?您还可以使用 CSV、JSON、XML 或您自己的一些文本格式,所有这些都可能比 MySQL 更快,并且比 PHP 更易于维护。
  • @MikeW 嗯... PHP 和 JSON 一样可维护,尤其是 PHP 5.4 中的 [...] 语法。而使用 PHP 意味着无需进行任何处理,只需读取数组即可。
  • 好吧,在这里我们可能会在意见上有所不同,所以我会相应地标记这个问题。
  • 你有没有使用任何配置文件?如果是这样,请使用相同的方式存储不变的数据。
  • 嗯,有many ways to store stuff。找到适合您使用数据的方式的数据库。

标签: php mysql


【解决方案1】:

似乎有些基准测试是有序的。

我整理了一些脚本来测试将数据存储为 PHP 数组、CSV 文件以及通过 PDO 访问的 MySQL DB。

阵列测试

这里是数组测试的脚本:

array-inc.php:

$data = array(
    array(
        "key"   => "something",
        "value" => "something else"
    ),
    array(
        "key"   => "something",
        "value" => "something else"
    ),
    array(
        "key"   => "something",
        "value" => "something else"
    ),
    array(
        "key"   => "something",
        "value" => "something else"
    ),
    array(
        "key"   => "something",
        "value" => "something else"
    )
);

array-test.php

$start = microtime( TRUE );

for( $i = 0; $i < 10000; ++$i ) {
    include( "array-inc.php" );
    $retrieve = $data[2];
}

$finish = microtime( TRUE );

print $finish - $start;

CSV 测试

以下是 CSV 测试的脚本:

值.csv:

key,value
something,something else
something,something else
something,something else
something,something else
something,something else

csv.php:

$start = microtime( TRUE );

for( $i = 0; $i < 10000; ++$i ) {
    $fp = fopen( "values.csv", "r" );

    $data = array();
    while(( $line = fgetcsv( $fp )) !== FALSE ) {
        $data[] = $line;
    }

    $retrieve = $data[2];
}

$finish = microtime( TRUE );

print $finish - $start;

MySQL 测试

这里是MySQL测试的脚本(表有id、key、value列,五行和值与上面两列相同):

mysql.php:

$start = microtime( TRUE );

for( $i = 0; $i < 10000; ++$i ) {
    $query = "SELECT * FROM `values` WHERE id = :id";
    $result = $pdo->prepare( $query );
    $result->execute( array( ":id" => 2 ));
    $retrieve = $result->fetch( PDO::FETCH_ASSOC );
}

$finish = microtime( TRUE );

print $finish - $start;

每一个都设置为从存储的数据中访问一个元素,并循环处理 10,000 次,以便更准确地测量时间。结果如下:

我对这些测试中的每一个运行了 3 次,并收到了以下值:

  • 阵列:
    • 1.050、1.020、1.114 秒
  • CSV:
    • 1.264、1.232、1.105 秒
  • MySQL:
    • 1.038、1.149、1.171 秒

似乎 CSV 是明显的输家,但 Array 和 MySQL 非常接近,而 Array 可能在性能上略微领先。随意调整上面的代码,以提供更符合您的环境的结果。

【讨论】:

  • 感谢您抽出宝贵时间如此彻底地回答。我还怀疑 MySQL 从查询缓存中获得:p 还有一些事情需要考虑,例如“如果 MySQL 不必提供不变的数据,它可以将更多资源用于更复杂的查询”。
  • 我也考虑了 MySQL 缓存,我怀疑你是正确的。鉴于此,以及您的其他评论,将数据存储为数组(甚至作为每次需要时都包含的外部文件)似乎是表现最好的。
【解决方案2】:

您的问题的答案是针对特定问题的。这是性能、内存和可维护性之间的权衡。即使您想说出候选解决方案的优缺点,您也需要假设一些参数。以下是影响您做出决定的参数:

  1. 数据大小:您拥有的数据的总大小。即您的数据库文件大小。

  2. 请求加载数据所需的平均内存大小:考虑上述参数和并发请求的平均数量,它们需要多少内存。

  3. 每个请求所需的总数据的平均比率:每次加载数据时,您将使用多少数据以及选择这部分数据的难易程度。

    李>
  4. 从整个集合中提取目标数据部分需要多少 (CPU) 时间:从简单的 PHP 数组到 MySQL SELECT 查询,它可能会有很大差异。

    李>

了解这些参数后,您可以提出一个解决方案是否更好的问题。无论如何,您的解决方案将是以下之一:

  • 包含在代码中。
  • 配置文件(XMLINICSVJSON 等)。
  • 数据库服务器 (MySQL)。
  • 本地数据库 (SQLite)。
  • 缓存在内存中(缓存服务器,例如 memcached,或者可能是 PHP's shared memory)。

我知道我没有回答您的问题,但那是因为除非您指定提到的参数,否则无法回答。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-01
    • 2013-09-10
    • 2014-07-28
    • 2012-05-10
    • 2011-11-26
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多