【问题标题】:Database Table Structure for a simple RPG简单 RPG 的数据库表结构
【发布时间】:2018-01-01 16:52:58
【问题描述】:

我目前正在使用 SQLite 练习并制作一个简单的基于文本的 RPG,但我需要一些有关表格结构的建议。

到目前为止,我已经提出了一个 "Player" 表来存储玩家信息。 “Inventory” 表,连接到其“玩家”ID。 一个“Item”表,其中包含所有项目。

这是我的问题。我有一个“武器”模型、“盾牌”“胸部”“腿”等. 对于每个项目类型的设备,每个可能包含 50-100 个项目。我应该将所有项目存储在 "Item" 表的长列表中还是应该制作子表?像“武器”表,“盾牌”表等并删除“物品”表?

感谢您的宝贵时间!

【问题讨论】:

    标签: android mysql database sqlite


    【解决方案1】:

    正确的答案应该是遵循公认的现实数据库设计指南,这在很大程度上取决于游戏的全部功能要求。

    但是,我建议解决方案既不是项目列表,也不是项目类型的单独表格。而是一个包含 "type" 列的项目表,该列引用表(武器、盔甲、收藏品(等)),也许还有一个 type 表。

    例如,武器有一个力量值(它击中的强度)和一个速度值(它击中的频率),但盔甲只有防御值,而收藏品有重量值。物品列表可能是一件相当复杂的事情,即在这个简单的场景中,它有 4 个额外的列,有相当多的冗余,即收藏品和盔甲仅使用 25%,而武器使用 50%,所以也许你可以引入更复杂的处理来仅使用 2 列。

    SQLite 明智的做法可能是:-

    CREATE TABLE IF NOT EXISTS rpg_player (_id INTEGER PRIMARY KEY, player_name TEXT);
    CREATE TABLE IF NOT EXISTS rpg_item(_id INTEGER PRIMARY KEY, type_reference INTEGER, item_subtype_reference INTEGER, UNIQUE(type_reference,item_subtype_reference));
    CREATE TABLE IF NOT EXISTS rpg_inventory(player_id INTEGER, item_id INTEGER, number_held INTEGER, PRIMARY KEY(player_id, item_id)) WITHOUT ROWID;
    CREATE TABLE IF NOT EXISTS rpg_item_types(_id INTEGER PRIMARY KEY, type_name TEXT, type_flags INTEGER);
    CREATE TABLE IF NOT EXISTS rpg_weapon(weapon_id INTEGER PRIMARY KEY, weapon_name TEXT, weapon_flags INTEGER, weapon_force INTEGER, weapon_speed INTEGER);
    CREATE TABLE IF NOT EXISTS rpg_armour(armour_id INTEGER PRIMARY KEY, armour_name TEXT, armour_flags INTEGER, armour_defence INTEGER);
    CREATE TABLE IF NOT EXISTS rpg_collectable(collectable_id INTEGER PRIMARY KEY, collectable_name TEXT, collectable_flags INTEGER, collectable_weight INTEGER);
    

    这些说填充为:-

    玩家表

    物品表

    包含所有项目的主项目表,以便轻松引用。 (例如在库存中)。一个条目有它自己的 unqiue id,它引用类型(武器、盔甲.....),然后是子类型表中的项目:-

    • 第一行的唯一 ID 为 1,(第一列)该项目的类型为 2(第二列)(rpg_item_types 中的 ID 2 表)(Armour)并且是 rpg_armour 表中 ID 为 5(第 3 列)的盔甲项目(手臂玩具)。
    • 同样,第 3 项是武器(第 1 列是 1,所以输入 1),它是武器表中 id 为 2 的武器(Great Sword)。

    • 仅引用其他表,但所有项目都有唯一 ID
    • type_reference 是类型,item_subtype_reference 是相应类型表(武器、盔甲、收藏品)中项目的 id
    • 根据UNIQUE(type_reference,item_subtype_reference) 设置了一个表约束,因此 type_reference 和 item_subtype_reference 的组合必须是唯一的

    库存表

    项目类型

    此表对每个项目的子类都有一个条目。

    子项目表

    模拟项目细节的表格,例如rpg_weapon 有一个 Weapon_force 和 Weapon_speed 列,而 rpg_armour 只有一个 armour_defence 列


    您可以使用以下内容创建一个简单的项目列表(输出方式):-

    --LIST ALL ITEMS
    SELECT 
        CASE 
            WHEN type_name = 'Weapon' THEN weapon_name || ' Type (' || type_name || ')'
            WHEN type_name = 'Armour' THEN armour_name || ' Type (' || type_name || ')'
            WHEN type_name = 'Collectable' THEN collectable_name || ' Type (' || type_name || ')'
        END AS description
        FROM rpg_item
        JOIN rpg_item_types ON type_reference = rpg_item_types._id
        LEFT JOIN rpg_weapon ON item_subtype_reference = weapon_id
        LEFT JOIN rpg_armour ON item_subtype_reference = armour_id
        LEFT JOIN rpg_collectable ON item_subtype_reference = collectable_id
    

    导致:-

    以下将列出所有库存项目:-

    SELECT 
        CASE
            WHEN rpg_item.type_reference = 1 THEN 'Player - ' || player_name || ' has ' || weapon_name || ' it is a ' || type_name || ' it has a force of ' || weapon_force
            WHEN rpg_item_types.type_name = 'Armour' THEN  'Player - ' || player_name || ' has ' || armour_name || ' it is a ' || type_name || ' with a defence rating of ' || armour_defence
            WHEN rpg_item.type_reference = 3 THEN 'Player - ' || player_name || ' has ' || collectable_name || ' it is a ' || type_name || ' it has a weight of ' || collectable_weight
        END AS description
        FROM rpg_inventory
        JOIN rpg_player ON player_id = rpg_player._id
        JOIN rpg_item ON rpg_inventory.item_id = rpg_item._id
        JOIN rpg_item_types ON rpg_item.type_reference = rpg_item_types._id
        LEFT JOIN rpg_weapon ON rpg_item.item_subtype_reference = rpg_weapon.weapon_id
        LEFT JOIN rpg_armour ON rpg_item.item_subtype_reference = rpg_armour.armour_id
        LEFT JOIN rpg_collectable ON rpg_item.item_subtype_reference =rpg_collectable.collectable_id
    

    基于以上的结果(哎呀,没有人持有武器):-

    一个简单的WHERE 子句 (WHERE player_id = ?) 会将列表限制为单个玩家。

    • 例如WHERE player_id = 2 只会列出 Fredrica 的库存。

    您可能想复制并粘贴以上内容并在 SQLite 工具中使用它,周围有很多(我个人对 SQLite Manager 非常满意,其他人会推荐其他工具,以上所有内容都是使用这样的工具)。您可能很有可能仅使用这样的工具来创建核心数据库访问功能。

    【讨论】:

    • 太棒了!谢谢你:)
    猜你喜欢
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 2021-01-13
    • 2012-02-02
    • 1970-01-01
    相关资源
    最近更新 更多