A veces surgen situaciones en las que la solución al problema de recuperar datos de una base de datos relacional no se ajusta a las capacidades del ORM utilizado en el proyecto, por ejemplo, ya sea por la velocidad insuficiente del ORM en sí mismo o por las consultas SQL no bastante óptimas generadas por él. En este caso, generalmente tiene que escribir consultas manualmente.El problema es que los datos de la base de datos (incluso en respuesta a una solicitud JOIN) se devuelven como una matriz bidimensional "plana" que no refleja la compleja estructura de "árbol" de los datos de la aplicación. Es extremadamente inconveniente trabajar con una matriz de este tipo, por lo tanto, se requiere una solución más o menos universal para llevar esta matriz a una forma más adecuada de acuerdo con un patrón dado.La solución fue encontrada, conveniente y lo suficientemente rápida.Qué rápido
Para evaluar la velocidad de la biblioteca, armé un pequeño banco de pruebas en el que se compara la velocidad de mi biblioteca con la velocidad de Eloquent. Para las mediciones, se usó el paquete phpbench.Para desplegar un stand en casa:git clone https://github.com/hrustbb2/env-arrayproc-bench.git
cd env-arrayproc-bench
./env
Aquí utilicé la herramienta descrita en mi artículo anterior .Luego en el menú seleccionamos: 1 Desarrollar, luego: 1 Construir, luego 2 Implementar y Arriba;Luego ejecute las pruebas 5. Ejecute pruebasHay 3000 libros en la base de datos. Los resultados son los siguientes:+-----------------+-----+------+------+-------------+--------------+
| subject | set | revs | iter | mem_peak | time_rev |
+-----------------+-----+------+------+-------------+--------------+
| benchEloquent | 0 | 1 | 0 | 76,442,912b | 12,781.612ms |
| benchEloquentId | 0 | 10 | 0 | 5,123,224b | 16.432ms |
| benchProc | 0 | 1 | 0 | 36,364,176b | 1,053.937ms |
| benchProcId | 0 | 10 | 0 | 4,462,696b | 7.684ms |
+-----------------+-----+------+------+-------------+--------------+
benchEloquent - extrae todos los libros con los autores usando EloquentbenchEloquentId - saca un cierto libro con los autores usando Eloquent (10 veces)benchProc - saca todos los libros con los autores usando la bibliotecabenchProcId - saca un cierto libro con los autores usando la biblioteca (10)para actuar las pruebas no son lo suficientemente representativas, pero la diferencia es notable, tanto en tiempo de ejecución como en consumo de memoria.Cómo funciona
Instalar en pc:composer require hrustbb2/arrayproc:v1.0.0
Además, por ejemplo (extremadamente simple), imagine que tenemos una base de datos de libros y autores con la siguiente estructura.
La tarea es sacar todos los libros con sus autores.La solicitud se verá así:SELECT
books.id,
books.name,
authors.id,
authors.name
FROM
books
LEFT JOIN relations ON relations.books_id = books.id
LEFT JOIN authors ON authors.id = relations.authors_id
En respuesta, obtenemos tal conjunto de datos.La matriz es bidimensional, algunos campos están duplicados, por conveniencia necesita convertirlo[
1 => [
'id' => 1,
'name' => 'book1',
'authors' => [
2 => [
'id' => 2,
'name' => 'author2'
],
4 => [
'id' => 4,
'name' => 'author4'
],
6 => [
'id' => 6,
'name' => 'author6'
],
]
],
2 => [
'id' => 2,
'name' => 'book2',
'authors' => [
2 => [
'id' => 2,
'name' => 'author2'
],
3 => [
'id' => 3,
'name' => 'author3'
],
6 => [
'id' => 6,
'name' => 'author6'
],
7 => [
'id' => 7,
'name' => 'author7'
],
]
],
]
Para hacer esto, modifique ligeramente nuestra solicitud:
SELECT
books.id AS book_id,
books.name AS book_name,
authors.id AS author_id,
authors.name AS author_name
FROM
books
LEFT JOIN relations ON relations.books_id = books.id
LEFT JOIN authors ON authors.id = relations.authors_id
Aquí establecemos alias en la sección SELECCIONAR: para campos con datos sobre libros, alias con el prefijo 'libro_', y para campos con información sobre autores con el prefijo 'autor'.Luego, convertimos la respuesta de la base de datosuse hrustbb2\arrayproc\ArrayProcessor;
$arrayProcessor = new ArrayProcessor();
$config = [
'prefix' => 'book_',
'authors' => [
'prefix' => 'author_',
]
]
$booksData = $arrayProcessor->process($conf, $rows)->resultArray();
donde:$ rows es la respuesta de la base de datos en forma de una matriz de objetos / stdClass ()$ config es una matriz asociativa que refleja la estructura de datos de la matriz resultanteComo resultado, en $ booksData tenemos una matriz en forma de árbol que tiene la estructura descrita en $ config, llena con los datos correspondientes.Algo como esto.