Laravel开发万智牌卡牌数据库如何设计赛制合法性关联表
万智牌卡牌合法性表设计方案
你最初设想的三张表的结构方向完全正确,是当前场景下的最优解,具体设计和关联逻辑如下:
1. 数据库表结构设计
formats 赛制表
存储所有赛制的基础信息:
- id:主键,自增
- name:赛制名称,比如标准、近代、指挥官,需加唯一索引
- 可选扩展字段:赛制描述、上线时间、是否启用等
card_singles 单卡表
存储所有单卡的基础信息:
- id:主键,自增
- name:卡牌名称,需加普通索引
- 可选扩展字段:法术力费用、卡牌类型、稀有度、画师、所属系列、卡牌Oracle文本等
legalities 合法性关联表
这是赛制和单卡多对多关系的中间表,额外存储合法性状态:
- id:可选主键,自增,也可直接用
card_single_id+format_id作为联合主键 - card_single_id:外键,关联
card_singles.id,加索引 - format_id:外键,关联
formats.id,加索引 - status:合法性状态,可选值为
legal、not_legal、banned、restricted,加索引
优化建议:给
format_id、status、card_single_id三个字段加联合索引,可直接覆盖你最常用的「按赛制+状态查卡牌」的查询需求,大幅提升查询性能,避免全表扫描。
2. Laravel 模型关联配置
分别创建Format、CardSingle两个Eloquent模型,配置多对多关联即可:
Format 模型
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsToMany; class Format extends Model { protected $fillable = ['name', 'description']; public function cardSingles(): BelongsToMany { return $this->belongsToMany(CardSingle::class, 'legalities') ->withPivot('status'); } }
CardSingle 模型
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsToMany; class CardSingle extends Model { protected $fillable = ['name', 'cost', 'type', 'rarity']; public function formats(): BelongsToMany { return $this->belongsToMany(Format::class, 'legalities') ->withPivot('status'); } }
3. 常用查询实现示例
查询指定赛制下指定合法性的所有卡牌
比如查询标准赛制下所有legal的卡牌:
$legalStandardCards = Format::where('name', '标准') ->firstOrFail() ->cardSingles() ->wherePivot('status', 'legal') ->paginate(20); // 支持分页
查询单张卡在所有赛制下的合法性
比如查询「黑莲花」的全赛制合法性:
$blackLotusLegalities = CardSingle::where('name', '黑莲花') ->firstOrFail() ->formats ->pluck('pivot.status', 'name');
批量更新赛制禁牌表
比如近代赛制更新禁牌表,批量调整合法性:
$modernFormat = Format::where('name', '近代')->firstOrFail(); $modernFormat->cardSingles()->sync([ 123 => ['status' => 'banned'], // 123为对应卡牌ID 456 => ['status' => 'restricted'], // 其他需要调整的卡牌 ], false); // 第二个参数设为false,不会删除不在列表中的已有关联
内容的提问来源于stack exchange,提问作者bbarringer
相关产品推荐
相关产品推荐

