You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter+SQL构建商城/物品系统:物品合理结构设计咨询

解决方案建议

一、现有方案的可行性说明

你当前用本地availableProducts列表匹配数据库ID的方案,在物品总数不多、属性不会频繁变更的场景下完全可行。但要注意两个细节:

  • 要保证本地列表和数据库的一致性,后续如果物品属性更新,本地包必须同步迭代,否则会出现数据不匹配的问题
  • 可以给Item基类加个type枚举字段,从数据库拿到ID后,直接通过类型字段快速匹配对应子类,避免类型判断混乱

二、两种数据库设计方案对比

1. 单表+类型字段(推荐新手起步)

直接在boughtItems表中新增item_type字段(用VARCHAR或枚举类型,值设为weapon/stable这类标识),保留id/name/price这类通用字段,不同物品的特殊属性用JSON字段存储(比如武器的attack/durability、坐骑的speed/capacity)。

优势:

  • 实现简单,不用维护多张表,查询已购物品只需要一次SQL
  • Flutter端处理省心:查询后根据item_type字段,把JSON属性反序列化为对应的子类即可

表结构示例:

CREATE TABLE boughtItems (
  id INTEGER PRIMARY KEY,
  item_type VARCHAR(20) NOT NULL,
  name TEXT NOT NULL,
  price INTEGER NOT NULL,
  properties TEXT NOT NULL -- 存储JSON格式的特殊属性
);

Flutter端解析示例:

List<Item> parseBoughtItems(List<Map<String, dynamic>> dbData) {
  return dbData.map((row) {
    final type = row['item_type'];
    final props = jsonDecode(row['properties']);
    switch (type) {
      case 'weapon':
        return WeaponItem(
          id: row['id'],
          name: row['name'],
          price: row['price'],
          attack: props['attack'],
          durability: props['durability'],
        );
      case 'stable':
        return StableItem(
          id: row['id'],
          name: row['name'],
          price: row['price'],
          speed: props['speed'],
          capacity: props['capacity'],
        );
      default:
        throw Exception('Unknown item type');
    }
  }).toList();
}

2. 分表设计(适合属性差异极大的复杂场景)

如果不同类型物品的属性完全不重叠,且未来会频繁新增属性或物品类型,可以拆分出weapons、stable_items等独立表,boughtItems表只存item_id和item_type,查询时通过关联表获取具体属性。

优势:

  • 数据结构更规范,避免JSON字段灵活性带来的脏数据问题
  • 针对单一物品类型的查询效率更高

劣势:

  • 实现复杂度高,需要处理多表关联查询,Flutter端还要合并多数据源的结果

表结构示例:

-- 已购记录表
CREATE TABLE boughtItems (
  id INTEGER PRIMARY KEY,
  item_id INTEGER NOT NULL,
  item_type VARCHAR(20) NOT NULL,
  purchase_time DATETIME NOT NULL
);

-- 武器属性表
CREATE TABLE weapons (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  price INTEGER NOT NULL,
  attack INTEGER NOT NULL,
  durability INTEGER NOT NULL
);

-- 坐骑属性表
CREATE TABLE stable_items (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  price INTEGER NOT NULL,
  speed INTEGER NOT NULL,
  capacity INTEGER NOT NULL
);

查询已购武器示例:

SELECT b.*, w.* FROM boughtItems b
JOIN weapons w ON b.item_id = w.id
WHERE b.item_type = 'weapon';

三、针对你的具体建议

作为SQL新手,优先选单表+类型字段+JSON属性的方案:

  1. 开发成本低,能快速验证商城核心逻辑
  2. 后续如果物品类型或属性变复杂,再迁移到分表方案也不晚
  3. 结合Flutter的JSON序列化能力,处理子类转换非常方便

内容的提问来源于stack exchange,提问作者Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 05:01:00