Laravel结合MySQL单表列存储3个字符串数组 无需新建关联表方案咨询
最优实现方案:使用MySQL原生JSON列 + Laravel数组类型转换
这是兼顾性能、开发效率和功能适配的最优选择,完全符合你的需求。相比序列化存TEXT、逗号分隔字符串等替代方案,JSON列没有额外的解析开销,还支持结构化查询,适配你固定存储3个元素的场景完全没有问题。
- 性能层面:MySQL 5.7及以上版本支持的原生JSON列是二进制结构化存储,读取、写入、字段内检索的效率远高于普通文本存储方案,还支持针对JSON内部值创建索引,后续如果需要查询包含某个物品的desk记录也能满足性能要求。
- 功能层面:天然支持数组格式存储,不需要自行实现序列化/反序列化逻辑,Laravel原生支持JSON列的数组转换,操作和普通PHP数组完全一致。
第一步:编写Migration
创建desk表的migration文件写法如下,可直接实现3个可空默认值的需求:
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up() { Schema::create('desk', function (Blueprint $table) { $table->id(); // 定义JSON类型的items列,设置默认值为3个null的数组 $table->json('items')->default(json_encode([null, null, null])); // 其他字段按需添加 $table->timestamps(); }); } public function down() { Schema::dropIfExists('desk'); } };
注意:如果你使用的MySQL版本较低不支持JSON列的默认值,可以把列设置为可空,后续在模型属性里设置默认数组即可,对应写法为
$table->json('items')->nullable();
第二步:配置模型类型转换
在Desk模型里添加$casts配置,让Laravel自动处理JSON和PHP数组的双向转换:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Desk extends Model { protected $fillable = ['items']; protected $casts = [ 'items' => 'array', // 核心配置,自动完成序列化/反序列化 ]; // 如果migration里没设置默认值,在这里配置默认数组即可 protected $attributes = [ 'items' => [null, null, null], ]; }
第三步:日常使用示例
操作items字段和操作普通PHP数组完全一致,不需要额外处理:
// 写入数组 $desk = Desk::create([ 'items' => ['pencil', 'ruler', 'stapler'] ]); // 读取数组 $items = $desk->items; // 直接得到PHP数组:['pencil', 'ruler', 'stapler'] // 修改数组的某一项 $desk->items[2] = 'scissors'; $desk->save(); // 自动序列化为JSON存入数据库
性能优化建议
- 如果后续需要执行类似「查询所有包含
pencil的desk记录」的操作,可以给JSON列创建多值索引,SQL写法为ALTER TABLE desk ADD INDEX idx_items ((CAST(items AS CHAR(255) ARRAY)));,查询时用Laravel的whereJsonContains方法就能命中索引,性能和普通字段查询基本一致。 - 你当前固定存储3个元素的场景不会有任何性能损耗,无需担心额外开销。
内容的提问来源于stack exchange,提问作者Etra
相关产品推荐
相关产品推荐

