2013-02-19 76 views
1

我是数据库设计的新手,在为战斗游戏设计PostgreSQL数据库时遇到了很多麻烦。为性能选择索引和主键

在这个游戏中,玩家将在他们之间战斗,获得资源购买更好的武器和装甲。战斗将被记录下来供未来审查,战斗次数预计将迅速增加,例如,1K玩家每1K轮战斗将产生500K记录。

将游戏互动性降低为花费点数来升级战斗机的装备和性能。战斗由机器解决。

详情:

  • 特定类型的武器或防具的只能由每架一次应具备。
  • 战士几乎只会搜索id
  • 我经常需要搜索特定战斗机拥有哪些装备(武器和/或装甲),但我不期望搜索哪些战士拥有特定类型的武器。
  • 通常会通过winnerloser搜索战斗。
  • 两个给定fighters可以在不同的日期打多次,所以元组winner - loser不上表中是唯一combats
  • fighters表中含有大量将要经常检索到的所有在同一时间列(我创建两个与所有相关的信息类“战斗机”的对象随时战斗开始)

这是我当前的设计:

CREATE TABLE IF NOT EXISTS weapons (
    id serial PRIMARY KEY, 
    *** Game stuff *** 
); 

CREATE TABLE IF NOT EXISTS armors (
    id serial PRIMARY KEY, 
    *** Game stuff *** 
); 

CREATE TABLE IF NOT EXISTS fighters (
    id serial PRIMARY KEY, 
    preferred_weapon INT references weapons(id), 
    preferred_armor INT references armors(id), 
    *** Game stuff *** 
); 

CREATE TABLE IF NOT EXISTS combats (
    id serial PRIMARY KEY, 
    winner INT references fighters(id), 
    loser INT references fighters(id), 
    *** Game stuff *** 
); 

CREATE TABLE IF NOT EXISTS fighters_weapons (
    fighter INT NOT NULL references fighters(id), 
    weapon INT NOT NULL references weapons(id), 
    PRIMARY KEY(fighter, weapon) 
); 

CREATE TABLE IF NOT EXISTS fighters_armors (
    fighter INT NOT NULL references fighters(id), 
    armor INT NOT NULL references armors(id), 
    PRIMARY KEY(fighter, armor) 
); 

我的问题是:

  1. 您是否认为我的设计非常适合?
  2. 我已经看到很多包含id列的示例数据库作为每个表的主键。这有什么理由吗?我应该这样做,而不是我在fighters_weaponsfighters_armors上使用的多列主键?
  3. PostgreSQL为每个主键自动创建索引,但有几个表我不期望按它搜索(即,combats)。我应该删除性能指数吗? PostgreSQL抱怨现有的约束。
  4. 正如我将搜索fighters_weaponsfighters_armors通过fighter,以及combats通过winnerloser,你觉得我应该为所有这些表此列创建索引?
  5. 任何性能改进建议?最常用的操作将是:插入和查询战士,查询给定战士的装备和插入战斗。

感谢很多:)

+0

小挑剔:“松动”与“收紧”相反,“失去”与“找到”相反(所以你的专栏应该叫做'失败者' – 2013-02-19 15:27:47

+0

@a_horse_with_no_name这是真的。谢谢! – 2013-02-19 15:35:01

+0

从技术上来说,'combats'并不需要它自己的主键,它可以像使用其他几个关联表一样使用'winner' /'loser'元组。这种类型的游戏是实时的,基于回合的等等。 ?如果你想让我们给你更多的帮助,你需要给我们各种表格的完整布局(特别是“战士”)。嗯..我见过的大多数建议都倾向于说(例如'fighter'),你会想要每个主键上的索引,不管它是什么。 – 2013-02-19 16:36:03

回答

0

为了解决您的明确的问题:

2)它可以是最好,如果使用“天然”的值作为主键,即不是一个序列ID一个存在。在你不太可能使用序列号作为标识符的情况下,我会说最好不要添加它。 3)除非你打算很快将很多行插入到战斗表中,否则它可能不会对你的id列上的索引造成太大伤害。

4)如果索引{fighter,weapon}存在,那么在{fighter}上创建一个索引是不必要的,并且如果索引{fighter,armor}存在,就不需要在{fighter}上创建索引。一般来说,您不会从创建作为另一个多列索引前缀的索引中受益。另外,根据您所描述的访问模式,在战斗中创建{赢家}和{失败者}索引似乎是一个好主意。 5)除表格设计外,如果您自己安装了数据库,则可能需要设置一些数据库调整参数。如果有经验的数据库管理员已经建立了数据库,他/她可能已经为你做了这个。

+0

非常感谢;这非常有用。关于5),我自己管理数据库,但根本没有经验。将尝试搜索有关PSQL Tunning的信息。 – 2013-02-21 08:57:22