我想为一组玩家建模一个数据库实体。 每个玩家都应该拥有:
实现这样一个实体的最佳方法是什么(关系数据库和非关系数据库都适合我)?
最简单的解决方案当然是为每个角色保留一个不同的表。我还找到了 this 答案,这很好,但已经有 7 年历史了,可能已经过时了。还有其他想法吗?
这是一个示例数据集:
"name": "name1"
"role": "attack"
"strength": 10
"constitution": 5
"name": "name2"
"role": "attack"
"strength": 7
"constitution": 7
"name": "name3"
"role": "defense"
"health": 8
"resistence": 8
"name": "name4"
"role": "defense"
"health": 10
"resistence": 10
"name": "name5"
"role": "support"
"mana": 4
"willpower": 3
数据的面向对象结构
您已在
Character
群体中识别出多个类别,这些类别源自抽象角色 ,即 Attack
、Defense
和 Support
。每种角色根据类别具有不同的属性。
所以你心里清楚有一个 OOP 设计,并希望在数据库中实现它。可以使用多种设计模式:
Defense
)和父类表(此处为Character
)之间存在1:1的关系。这似乎有点矫枉过正了name
字段。再说一遍,这似乎有点矫枉过正。
类或关系?
您可以考虑另一种附加模型。它是一个类似于组件的设计,基于组合(在关系的 SQL 模式中):
character
桌子,其中有
id
、
name
和
role
id
、
property-id
(或名称)和
value
。
无 SQL
如果您想考虑非关系数据库,通常是“无 SQL 数据库”,那么您可以考虑基于文档的数据库,它非常适合处理类似于单继承表的结构。如果您选择组件设计,那么键值存储也可以是一种选择,但您仍然需要组装各个部分。这就是额外灵活性的代价;-)
你说多态?
多态性更多的是与类相关的行为,而不是描述对象的数据。由于这里不是行为问题,我猜您的意思是处理不同类型的数据(所以更多的是关于类)。如果我在这一点上错了,请告诉我。
但是,您应该让问题中包含多态性,因为它可以帮助其他不太了解 OOP 术语的人找到类似问题的解决方案
为了扩展
我已经整理了一个快速的 TypeDB
模式,应该适用于您的示例数据:在这里,我定义了一个实体层次结构,每个玩家角色attack-player
、defense-player
和
support-player
都扩展了抽象的
player
超类型。我还定义了一个属性层次结构,因此所有技能都扩展了一个抽象的
skill
超类型。每个玩家角色根据需要拥有不同的技能,并且他们都继承了
name
的
player
。
使用此架构,可以按如下方式插入示例数据:
insert
$player-1 isa attack-player,
has name "name1",
has strength 10,
has constitution 5;
$player-2 isa attack-player,
has name "name2",
has strength 7,
has constitution 7;
$player-3 isa defense-player,
has name "name3",
has health 8,
has resistance 8;
$player-4 isa defense-player,
has name "name4",
has health 10,
has resistance 10;
$player-5 isa support-player,
has name "name5",
has mana 4,
has willpower 3;
现在您的数据可以进行多态查询。要获得
attack
的"name1"
技能,您可以使用:
match
$player isa player,
has name "name1",
has attack $atk;
get $atk;
要获得"name1"
的所有技能,请使用:
match
$player isa player,
has name "name1",
has skill $skl;
get $skl;
要获取防守球员及其技能,请使用:match
$player isa defense-player,
has name $name,
has health $hlt,
has resistance $res;
get $name, $hlt, $res;
要获取所有拥有
mana
技能的玩家,无论其玩家角色如何,请使用:
match
$player isa player,
has name $name,
has mana $mna;
get $name, $mna;
要获得所有玩家及其所有技能,请使用:match
$player isa player,
has name $name,
has skill $skl;
get $name, $skl;