db::table()返回数组,model::get()返回对象;前者轻量无逻辑,适合配置查询;后者支持验证、事件、关联、自动转换等完整业务能力。

Db::table() 返回数组,Model::get() 返回对象
这是最直观、也最容易踩坑的区别。用 Db::table('user')->find(1) 拿到的是一个普通 PHP 数组,比如 ['id' => 1, 'name' => '张三'];而 UserModel::get(1) 拿到的是一个 UserModel 实例,它能调用模型里定义的获取器(getNickNameAttr)、修改器(setCreateTimeAttr)、自动完成(auto)等逻辑。
- 数组不能直接链式调用业务方法,对象可以——比如
$user->isVip()或$user->toSimpleArray() - 模型对象会触发
onAfterFind等事件,Db 不会 - 字段映射不一致时容易出错:Db 默认按数据库字段名返回,模型可通过
type配置或schema自动转类型(如statusint → boolean) - 如果只是读配置、查字典表、中间表统计,用 Db 更轻量;涉及用户状态流转、订单生命周期等,必须走模型
Db 类适合无业务逻辑的“快查”,模型适合有状态/规则的数据操作
比如查后台菜单列表、站点配置、日志统计总数,这些数据不参与业务判断、不需校验、不触发事件,Db::name('config')->where('type', 'site')->find() 就够了。但一旦要“创建订单”——需要检查库存、生成单号、扣减积分、发消息通知——这些逻辑放在 Db 调用里只会越写越乱。
- 模型支持
validate验证,Db 不校验,漏掉就直接写库 - 模型可定义
save()前后事件,Db 的insert()是纯执行,没钩子 - 关联查询差异明显:
UserModel::with('profile,orders')一行搞定,Db 得手写join+ 多次select+ 手动组装嵌套结构 - Db 支持原生 SQL 和参数绑定(
Db::query('SELECT * FROM user WHERE id IN ?', [$ids])),模型不推荐直接拼 SQL,破坏封装性
性能差异真实存在,但多数场景可忽略
基准测试下,Db 查询比同条件模型快 10%–20%,因为少了一层对象实例化和属性赋值。但这个差距只在单次查询、高频接口(如埋点上报、心跳检测)中敏感。
- 模型的额外开销主要来自:构造对象、反射读取配置、触发初始化事件、处理时间字段自动转换
- 开启
cache后,模型首次查询慢,后续命中缓存,Db 却每次都要走一遍查询流程 - 若用
UserModel::withoutEvent()->hidden(['password'])->find(1)关闭事件+隐藏字段,性能已非常接近 Db - 真正拖慢响应的从来不是模型本身,而是没加索引的 where、N+1 关联、未复用查询构造器
中间表、动态表、临时表别硬套模型
多对多关系里的中间表(如 user_role),一般不单独建模型——它没有独立业务含义,只是关联凭证。这时候用 Db::name('user_role')->where(['user_id' => 5])->delete() 更干净。
- 模型要求表结构稳定,字段名、类型需与模型属性对齐;Db 对字段零约束,适合字段经常变动的运营表
- 分表场景(如
log_202603)不适合固定模型,用Db::name('log_'.$date)->insert($data)更灵活 - 模型类文件缺失会导致 fatal error,Db 类只要配置正确就能运行,适合快速脚本或命令行任务
- 注意:Db 不支持模型的
append、visible、toJson()等输出控制,JSON 接口返回前得自己unset敏感字段
模型不是银弹,Db 也不是退化。该用对象封装时别图快写 Db,该甩开包袱直连时也别硬套模型——边界在哪,取决于那条数据有没有“身份”和“脾气”。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











