我是数据库设计的新手,在为战斗游戏设计 PostgreSQL 数据库时遇到了很多麻烦。
在这个游戏中,玩家将在他们之间进行战斗,获得资源来购买更好的武器和盔甲。战斗将被记录下来以备将来审查,预计战斗的数量将迅速增长,例如,1k 名玩家战斗 1k 回合将产生 500k 记录。
游戏交互性降低,需要花费点数来升级战士的装备和能力。战斗由机器解决。
详细信息:
- 每个战士只能拥有一次特定类型的武器或盔甲。
- 战士将几乎完全通过
id
进行搜索。 - 我经常需要搜索特定战士拥有哪些装备(武器和/或盔甲),但我不希望搜索哪些战士拥有特定类型的武器。
- 通常会按
获胜者
或失败者
搜索战斗。 - 两个给定的
fighters
可以在不同的日期进行多次战斗,因此元组winner
-loser
在combats 表中不是唯一的
fighters
表包含很多列,这些列通常会同时被检索(我创建了两个“Fighter”类的对象,其中包含战斗开始时的所有相关信息)
这是我目前的设计:
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)
);
我的问题是:
- 你觉得我的设计合适吗?
- 我见过很多包含
id
列作为每个表主键的示例数据库。有什么理由吗?我应该这样做而不是我在fighters_weapons
和fighters_armors
上使用的多列主键吗? - PostgreSQL 会自动为每个主键创建索引,但有几个表我不希望通过它来搜索(即
combats
)。我应该删除索引以提高性能吗? PostgreSQL 提示现有约束。 - 因为我将搜索
fighter
的fighters_weapons
和fighters_armors
,以及winner 的
和combats
loser
,你认为我应该为这些表的所有这些列创建索引吗? - 任何性能改进建议?最常用的操作是:插入和查询战斗机、查询给定战斗机的设备以及插入战斗。
非常感谢:)
最佳答案
要解决您的明确问题:
2) 最好使用“自然”值作为主键,即不是序列号,如果存在的话。如果您不太可能使用序列号作为标识符,我会说最好不要添加它。
3) 除非您打算非常快速地向 combats 表中插入许多行,否则在 id 列上建立索引可能不会对您造成太大伤害。
4) 如果索引 {fighter, weapon} 存在,则无需在 {fighter} 上创建索引,类似地,如果索引 {fighter, armor} 存在,则无需在 {fighter} 上创建索引。通常,您不会从创建作为另一个多列索引前缀的索引中受益。另外,考虑到您所描述的访问模式,为战斗创建 {winner} 和 {loser} 索引似乎是个好主意。
5) 除了表设计之外,如果您自己安装了数据库,您可能还需要设置一些数据库调优参数。如果有经验的数据库管理员设置了数据库,他/她可能已经为您完成了。
关于sql - 为性能选择索引和主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14960801/