请问假如有1000个配置项,如何避免使用这种写法,更加优雅的写法是怎样的?

表结构:

id key value
1 logo
2 admin_logo

如题,该表存储各种配置项,假如目前有1000多个配置,如下写法肯定是行不通的,有没有更优雅的写法(暂时先不提缓存)

public function save(Request $request)
{
    foreach ($request->all() as $key => $value) {
        Setting::updateOrCreate([
            'key' => $key,
            'value' => $value
        ]);
    }
    return Result::success();
}
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 11
public function save(Request $request)
{
    DB::transaction(function () use ($request) {

            $settings = Setting::all()->keyBy('key');

            foreach ($request->all() as $key => $value) {
                if (isset($settings[$key])) {
                    if ($settings[$key]->value <> $value) {
                        $settings[$key]->update(['value' => $value]);
                    }
                } else {
                    Setting::create([
                        'key' => $key,
                        'value' => $value
                    ]);
                }
            }
        });
    return Result::success();
}
3年前 评论
半人间 3年前
8565012 (作者) 3年前

要不改成Redis哈希吧,感觉挺适合的。

 Redis::HMSET('config',$request->all());

/*
Redis::HMSET('config',['logo' => 'http://baidu.com','admin_logo' => 'http://...']);
*/
3年前 评论
岁月流沙

减少数据库操作,减少数据处理的量级,事务没加可自行添加

// 获取所有数据
$requestData = $request->all();
// 获取提交的键
$requestKey = array_keys($requestData);
// 获取数据库存在的数据
$existsData = Setting::whereIn('key', $requestKey)->get();
// 取出键
$existsKey = $existsData->pluck('key')->toArray();
// 获取需要插入的键
$insertConfigData = array_diff($existsKey, $requestKey);
// 构造批量插入数据
$insertData = collect($requestData)->only($insertConfigData)->map(function ($item, $key) {
    return [
        'key' => $key,
        'value' => $item,
    ];
})->toArray();
// 批量插入
Setting::insert($insertData);
// 逐个更新已存在键
$existsData->map(function ($item) use ($requestData) {
    $item->value = $requestData[$item->key];
    $item->save();
});

不过感觉这种设计不合理,1000个配置这么处理???,可以换个方案

3年前 评论
一个人的江湖 (楼主) 3年前

写成单个key查询配置不就好了,配置项不都是独立存在的吗

3年前 评论

@Linxb

file 前端是这么搞的 :joy: :joy:,那么多配置项用同一个保存

3年前 评论
岁月流沙

@一个人的江湖 为什么不每个tab 设计成一条数据,反正前端每次都会传tab的所有值给你,直接单条数据全量更新

id key value
1 权益配置项(英文键) 权益配置项所有值的json或者序列化
3年前 评论
一个人的江湖 (楼主) 3年前
xujinhuan 3年前

可以生产配置文件xx.config, 修改、添加直接操作文件不就OK了

3年前 评论
一个人的江湖 (楼主) 3年前

是想批量更新数据?将key字段设置为唯一索引,然后用replace into或者on duplicate key update就好了

3年前 评论

试试这种方式? github.com/baijunyao/laravel-bjybl...

   /**
     * @param array<int,array<string,mixed>> $multipleData
     *
     * e.g.
     * $multipleData = [
     *     [
     *         'id' => 1 ,
     *         'name' => 'baijunyao'
     *     ],
     *     [
     *         'id' => 2 ,
     *         'name' => 'Junyao Bai'
     *     ]
     * ]
     */
    public function updateBatch(array $multipleData = []): int
    {
        if (empty($multipleData)) {
            return 0;
        }

        $tableName       = config('database.connections.mysql.prefix') . $this->getTable();
        $updateColumn    = array_keys($multipleData[0]);
        $referenceColumn = $updateColumn[0];

        unset($updateColumn[0]);

        $whereIn = '';
        $sql     = 'UPDATE ' . $tableName . ' SET ';

        foreach ($updateColumn as $uColumn) {
            $sql .= $uColumn . ' = CASE ';

            foreach ($multipleData as $data) {
                $sql .= 'WHEN ' . $referenceColumn . " = '" . $data[$referenceColumn] . "' THEN '" . $data[$uColumn] . "' ";
            }

            $sql .= 'ELSE ' . $uColumn . ' END, ';
        }

        foreach ($multipleData as $data) {
            $whereIn .= "'" . $data[$referenceColumn] . "', ";
        }

        $sql = rtrim($sql, ', ') . ' WHERE ' . $referenceColumn . ' IN (' . rtrim($whereIn, ', ') . ')';

        return DB::update($sql);
    }
3年前 评论

"如下写法肯定是行不通的", 为什么要这么说呢,我感觉这么写问题也不是太大

3年前 评论

delete in keys
然后在把接收到的值全部添加进去,2条sql解决所有变更😄

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!