在服务器上存储多维数组的最佳方法?

时间:2008-12-29 01:53:19

标签: database arrays

我正在开发一款基于网络的回合制策略游戏,该游戏在10x10的主板上进行。

每块瓷砖代表一块土地,并有自己的统计数据(例如,收入,人口,生育率,自然资源)。

每次客户端加载它都将下载游戏的所有信息(即,不需要加载仅一个图块的统计数据)。电路板尺寸是静态的,也就是说,总有100个瓷砖。

将这些数据存储在服务器上的最佳选择是什么? (忽略键等)

  • 在数据库中:包含(每个图块的统计数量)字段和每个游戏100条记录的表格。
  • 在数据库中:每个游戏有一条记录的表格和100 *(num stats / tile)字段
  • 在平面文件中。

7 个答案:

答案 0 :(得分:1)

这个确切的问题是在#django IRC频道上提出的,虽然提问者想要一个可变大小的游戏板用于不同的屏幕。

总体建议是先使用一个漂亮,干净,规范化的方法,如果遇到性能问题,优化到非规范化状态。首先进行规范化路由的主要原因是数据库是为相当容易地处理大量关系而构建的,并且如果它们不经常更改,可以轻松地缓存它获得的结果。

标准化设置的意思是(伪代码):

Table Board
{
    BigInt id;
    String name;
    Date date_played;
    etc...
}

Table Tile
{
    BigInt id;
    ForeignKey board;  // what board the tile belongs to
    ManyToMany items;  // items on this tile
    ManyToMany players;   // players on this tile
    etc...
}

Table Item
{
    BigInt id;
    String name;
}

Table Player
{
    BigInt id;
    String name;
}

// many-to-many link table
Table TileItem
{
    BigInt id;
    BigInt tile; // tile id
    BigInt item;  // item id
}

// do the same thing for players
Table TilePlayer
{
    BigInt id;
    BigInt tile;
    BigInt player;
}

每个电路板你将存储100条记录,但如果你问我,它是值得的。这使得查找所有游戏板区块变得容易。写入单个图块可以只使用其ID,没有困难的行解释或任何其他内容。

答案 1 :(得分:1)

使用数据库,每个磁贴一行。由于每个游戏转弯可能不会修改很多棋盘,最好将它们分开。同样,如果你需要

Tiles (
    tile_id bigint autoincrement;
    game_id bigint; // foreign key to game table
    x tinyint;
    y tinyint;
    fertility type;
    // etc.
    primary key (tile_id)
    unique key (game_id, x, y)
);

Games (
   game_id bigint autoincrement;
   status enum(pendingplayers, started, finished, pendingdeleteorarchive)
   turn_number int;
   date_started date;
   date_ended date;
);

在数据库中使用这些东西的一个好处是它可以在更新内容时省去一些工作。例如,如果你的一个土地的特征在每个回合发生变化,你可以只更新数据库而不是循环遍历瓷砖:

Update tiles set fertility = fertility * 0.99 where game_id = :x and land_type = 'forest';

答案 2 :(得分:0)

我会创建一个表格,其中每一行代表游戏中的一个图块。

然后,我会有一个X(从1到10)和Y(从1到10)的列。根据您的要求,您还可以存储它是哪个游戏(如果您想一次保留多个游戏)以及哪个游戏(如果您想保留游戏历史记录)。

所以你会:

平铺:   游戏ID
  转入int   X int   Y int   收入   人口   生育能力   等

主键是前4列。 GameID可能最终成为Game表的外键。

答案 3 :(得分:0)

从实体之间的实体关系图开始。我可以从你的简短描述中看到一些:

每场比赛一局 游戏有一个时间戳显示它何时启动 董事会有很多瓷砖 - 现在10x10,可能是任意的 磁贴有很多统计信息

还有其他一些你似乎放弃了。转而暗示不止一个玩家。一场比赛会有很多球员。

您可能希望为统计信息添加时间戳并保留更新历史记录。

这是一个面向对象的系统吗?你想出一个对象模型吗?我先从那开始。

答案 4 :(得分:0)

如果您不打算在电路板上搜索或订购数据,或者我会说平面文件可以正常工作。但是您的用户可能“希望”住在数据库中?然后电路板数据也适合那里。也许只需将电路板存储在一个varchar字段中,无论哪种格式最适合您,XML或序列化等等。

答案 5 :(得分:0)

你的问题不完整。

数据库用于(1)查询和(2)更新。您既未提及对数据的查询或更新。

存储数据对数据库来说并不是特别好用。如果要存储数据,通常使用简单文件。数据库定期备份到简单文件,以便进行长期存储,备份和恢复。

如果没有查询也没有更新,那么一个简单的文件就可以了。

但是,如果存在查询或更新,则数据库可能有意义。当然,具体结构取决于查询或更新的性质。

答案 6 :(得分:0)

如果玩家在单个“转弯”上的操作只能影响单个单元格(或一小组相邻单元格),那么您希望以允许部分更新的方式存储数据,而无需重写整个板块每次都到磁盘(并读取整个电路板)。

鉴于每场比赛的细胞数量很少,我会倾向于使用{游戏ID,x坐标,y坐标}键的数据库。