我要稍微不同意所有人,并说关系方法在这里是合理的。这里有趣的是,项目可以具有多个角色。主要问题将是这种关系布局和代码中的OO布局之间的映射不会让人感到“自然”,但是我认为在数据库端可以清晰地表达多个角色(无需怪异的编码或冗余,只需加入即可) 。
首先要确定的是多少数据是特定于项目的,以及给定类型的所有项目共享多少数据。
如果所有数据都是特定于项目的,这就是我要做的事情:
// ITEMS table: attributes common to all items
item_id | name | owner | location | sprite_id | ...
1 | Light Saber | 14 (Tchalvek) | 381 (Tchalvek house) | 5663 | ...
// WEAPONS table: attributes for items that are weapons
item_id | damage | damage_type | durability | ...
1 | 5 | sharp | 13 | ...
// LIGHTING table: attributes for items that serve as lights
item_id | radius | brightness | duration | ...
1 | 3 meters | 50 | 8 hours | ...
在这种设计中,每个项目以及所有(或大多数)项目具有的属性都在“项目”表中。一个项目可以扮演的每个其他角色是一个单独的表。
如果您想将其用作武器,则可以在“武器”表中查找它。如果在那里,那么它可以用作武器。如果不存在,则不能用作武器。记录的存在告诉您它是否是武器。并且如果存在,则其所有特定于武器的属性都存储在此处。由于这些属性是直接存储的,而不是以某种编码形式存储的,因此您可以使用它们执行查询/过滤。(例如,对于游戏的指标页面,您可能希望按武器损坏类型来汇总玩家,并且可以通过一些联接和group-by Damage_type来做到这一点。)
一个项目可以具有多个角色,并且存在于多个角色特定的表中(在此示例中,武器和照明都存在)。
如果它只是一个布尔值,例如“这是可保持的”,我将其放入Items表中。可能值得在其中缓存“这是武器”等内容,这样就不必在武器和其他角色表上进行查找。但是,它增加了冗余,因此您必须小心使其保持同步。
如果某些数据不会因每个项目而有所不同,则Ari建议在每种类型中都有一个附加表的建议也可以使用此方法。例如,如果武器损坏在每个项目上没有变化,但是角色仍然在每个项目上变化,则可以将共享武器属性分解到表中:
// WEAPONS table: attributes for items that are weapons
item_id | durability | weapon_type
1 | 13 | light_saber
// WEAPONTYPES table: attributes for classes of weapons
weapon_type_id | damage | damage_type
light_saber | 5 | energy
另一种方法是,项目所扮演的角色不会随项目而变化,而只会因项目类型而变化。在这种情况下,您可以将item_type放入Items表中,并可以在ItemTypes表中存储“是否是武器”,“是否可以固定”和“是否轻便”之类的属性。在此示例中,我还使项目名称不随每个项目而变化:
// ITEMS table: attributes per item
item_id | item_type | owner | location
1 | light_saber | 14 (Tchalvek) | 381 (Tchalvek house)
// ITEMTYPES table: attributes shared by all items of a type
item_type | name | sprite_id | is_holdable | is_weapon | is_light
light_saber | Light Saber | 5663 | true | true | true
// WEAPONTYPES table: attributes for item types that are also weapons
item_type | damage | damage_type
light_saber | 5 | energy
物品类型和武器类型很可能在游戏中不会改变,因此您可以将这些表一次加载到内存中,然后在哈希表中查找这些属性,而不用数据库联接。