在数据库中存储计算字段的最佳做法是什么。
例如,假设一个表具有字段height、weight、bmi
用户输入身高体重值,bmi字段自动填充。如何用表单实现。
体重指数公式$体重指数=体重/(身高 * 身高)
已尝试以下配置文件模型
protected $table = 'profiles';
protected $fillable = ['user_id', 'weight', 'height', 'dob', 'age', 'bmi'];
public function user(){
return $this->belongsTo(User::class, 'user_id');
}
protected static function boot() {
parent::boot();
static::saving(function($model){
$model->bmi = $model->weight / ($model->height * $model->height);
$model->age = (date('Y') - date('Y',strtotime($model->dob)));
});
}
剖面控制器
public function store(Request $request)
{
$profile = new Profile();
$profile->weight = $request->get('weight');
$profile->height = $request->get('height');
$profile->dob = $request->get('dob');
$profile->age;
$profile->bmi;
$profile->save();
return back()->with('success', 'Your profile has been updated.');
}
但我收到一个错误
Illuminate \ Database \ QueryException (42S22)
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'weight' in 'field list' (SQL: insert into `users` (`weight`, `height`, `dob`, `bmi`, `age`, `created_by`, `updated_by`, `updated_at`, `created_at`) values (60, 175, 1988-04-03, 0.0019591836734694, 30, 2, 2, 2018-03-08 20:06:02, 2018-03-08 20:06:02))
6条答案
按热度按时间uinbv5nw1#
您可以在模型的
boot
方法中执行此操作:mccptt672#
在数据库中存储计算字段的最佳做法是什么。
一般来说,不要。它是冗余的--您的数据库已经拥有计算它所需的所有信息,那么为什么还要存储冗余数据呢?
而是将an accessor放在模型上:
然后可以执行
$this->bmi
以获得计算值。如果你必须在数据库中有它,使用一个Eloquent事件,你可能想挂钩到
saving
事件。gtlvzcf83#
从Laravel 5.3和MySQL 5.7开始,您可以使用列修饰符
virtualAs
和storedAs
为MySQL创建VIRTUAL
(读取行时求值) 或STORED
(插入或更新行时求值并存储) 生成的列。我在下面的示例中使用了
virtualAs
...jdzmm42g4#
在数据库中存储计算字段的最佳做法是什么。
这取决于您的用例。如果您使用的是关系数据库,并且您的用例不涉及大数据(在数量、种类或速度方面),最佳实践是不要存储计算字段,并动态计算它们。
如果您使用的是noSQL数据库(例如MongoDB,Laravel支持它)或Hadoop,最佳实践是存储计算字段以避免计算时间。
这是时间复杂性和空间/存储复杂性之间的权衡。对于大数据/noSQL系统,存储计算字段,尤其是在计算复杂的情况下。对于关系数据库,动态计算它们,并保持数据不冗余
按如下方式使用访问器:
按如下方式使用模型事件:
f1tvaqid5#
如果您的DBMS支持计算列(即生成列),您可以考虑使用它们。
亮点:
您可以在迁移过程中执行代码来创建它。例如,我有一个用例,我想简化确定某个内容当前是否已发布的过程,我是这样做的:
然后在从数据库中检索记录后,我可以通过简单地检查来确定它是否已发布...
如果我想从数据库中查询它,我可以很容易地做到...
注意,这个语法是针对T-SQL的,因为我的项目中的RDBMS是MSSQLServer。然而,其他流行的DBMS也有类似的特性。
ALTER TABLE dbo.产品添加零售价值AS(可用数量 * 单价 * 1.35);
更改表t1添加列c2 INT,生成的INT始终作为(c1 + 1)存储;
ALTER TABLE emp2 ADD(收入AS(薪金+(薪金 * 佣金百分比)));
PostgreSQL似乎还不支持它,但是this SO回答提供了一个不错的解决方案。
dohp0rv56#
另一种方法是在迁移中创建一个计算列,该方法适用于所有DB:-
但这与MySQL数据库:-