php - three - laravel where or
¿Por qué Laravel/Eloquent no puede usar JOIN para la carga impaciente? (3)
Creo que, el enfoque de consulta conjunta tiene un inconveniente fatal cuando desea utilizar LIMIT y / o OFFSET.
$ users = User :: with (''cats'') -> get () - esto generará las siguientes 2 consultas.
select * from `users`
select * from `cats` where `user`.`id` in (''1'', ''2'', ''x'')
y no es una sola consulta como
select * from users inner join cats on cats.user_id = users.id
pero digamos, necesitamos paginar este conjunto de registros.
Usuario :: con (''gatos'') -> paginate (10) - esto generará las siguientes 2 consultas con límite.
select * from `users` limit 10
select * from `cats` where `user`.`id` in (''1'', ''2'', ''x'')
con una unión, será como
select * from users inner join cats on cats.user_id = users.id limit 10
recuperará 10 registros pero no significa 10 usuarios, porque cada usuario puede tener múltiples gatos.
También otra razón por la que creo que es, una relación entre db relacional y NOSQL db puede implementarse fácilmente con el enfoque de consulta separada
También como respuesta anterior, la identificación es ambigua, y tendría que prefijar cada declaración con el nombre de la tabla que no se desea.
Por otro lado, JOIN es costoso que EXISTS y EXISTS es más rápido porque no ordena que RDBMS recupere ningún dato, solo verifica si existen filas relevantes. EXISTS se utiliza para devolver un valor booleano, JOIN devuelve una tabla completamente diferente.
Para fines de escalabilidad, si se sigue la arquitectura de fragmentación, deberá eliminar los archivos JOIN. Esto fue practicado por interés durante la escalada. http://highscalability.com/blog/2013/4/15/scaling-pinterest-from-0-to-10s-of-billions-of-page-views-a.html
<?php
class Cat extends Eloquent {
public function user() {
return $this->belongsTo(''User'');
}
}
class User extends Eloquent {
public function cats() {
return $this->hasMany(''Cat'');
}
}
Ahora:
$cats = Cat::with(''user'')->get();
Realiza 2 consultas:
select * from `cats`
select * from `users` where `users`.`id` in (''1'', ''2'', ''x'')
¿Por qué no se puede simplemente hacer?
select * from cats inner join users on cats.user_id = users.id
Para aquellos que dicen que hay dos columnas de identificación en la tabla, eso podría evitarse fácilmente con alias:
select
c.id as cats__id,
c.name as cats__name,
c.user_id as cats__user_id,
b.id as users__id,
b.name as users__name
from cats c
inner join users b on b.id = c.user_id
ACTUALIZAR
Alguien señaló que Eloquent no conoce las columnas de las tablas de los modelos, pero creo que podrían proporcionar una manera de definirlas en el modelo para que luego puedan usar alias y hacer una combinación adecuada en lugar de una consulta adicional.
Mi conjetura es que esto permite cargar muchas de una a muchas relaciones. Digamos, por ejemplo, también teníamos una mesa para perros:
class User extends Eloquent {
public function cats() {
return $this->hasMany(''Cat'');
}
public function dogs() {
return $this->hasMany(''Dog'');
}
}
Ahora queremos cargarlos con el usuario:
$users = User::with(''cats'',''dogs'')->get();
No hay una combinación que funcione para combinarlas en una sola consulta. Sin embargo, hacer una consulta separada para cada elemento "con" funciona:
select * from `users`
select * from `cats` where `user`.`id` in (''1'', ''2'', ''x'')
select * from `dogs` where `user`.`id` in (''1'', ''2'', ''x'')
Entonces, aunque esta metodología puede producir una consulta adicional en algunas circunstancias simples, brinda la capacidad de cargar con entusiasmo datos más complejos donde el método de unión fallará.
Esta es mi suposición de por qué es así.
cats
probable que ambos, cats
y users
tengan una columna llamada id
, dejando su consulta sugerida ambigua. La carga ansiosa de Laravel utiliza una consulta adicional, pero evita este posible contratiempo.