que desea extraer los resultados de EAV (entidad-atributo-valor) mesas, o más específicamente tablas entidad de metadatos (piensa como wordpress wp_posts
y wp_postmeta
) como un "muy bien tabla relacional formateada ", para hacer algo de clasificación y/o filtrado.¿Cuál es el mejor rendimiento de Recuperación de resultados MySQL EAV como tabla relacional
He encontrado algunos ejemplos de cómo formatear los resultados dentro de la consulta (en lugar de escribir 2 consultas y unir los resultados en el código), pero me gustaría conocer el método "más eficiente" para hacerlo, especialmente para conjuntos de resultados más grandes.
Y cuando digo "más eficiente", me refiero a algo como los siguientes escenarios:
Consigue todas las entidades con apellido como XYZ
devolver una lista de entidades ordenado por el cumpleaños
por ejemplo convertir esto:
** ENTITY ** ----------------------- ID | NAME | whatever ----------------------- 1 | bob | etc 2 | jane | etc 3 | tom | etc ** META ** ------------------------------------ ID | EntityID | KEY | VALUE ------------------------------------ 1 | 1 | first name | Bob 2 | 1 | last name | Bobson 3 | 1 | birthday | 1983-10-10 . | 2 | first name | Jane . | 2 | last name | Janesdotter . | 2 | birthday | 1983-08-10 . | 3 | first name | Tom . | 3 | last name | Tomson . | 3 | birthday | 1980-08-10
en esto:
** RESULTS ** ----------------------------------------------- EID | NAME | first name | last name | birthday ----------------------------------------------- 1 | bob | Bob | Bobson | 1983-10-10 2 | jane | Jane | Janesdotter | 1983-08-10 3 | tom | Tom | Tomson | 1980-08-10
por lo que se puede ordenar o filtrar por cualquiera de los campos de metadatos.
he encontrado algunas sugerencias here, pero no puedo encontrar ninguna discusión de los cuales tiene un mejor rendimiento.
Opciones:
- GROUP_CONCAT:
SELECT e.*, GROUP_CONCAT(CONCAT_WS('||', m.KEY, m.VALUE) ORDER BY m.KEY SEPARATOR ';;') FROM `ENTITY` e JOIN `META` m ON e.ID = m.EntityID
- Multi-Ingreso:
SELECT e.*, m1.VALUE as 'first name', m2.VALUE as 'last name', m3.VALUE as 'birthday' FROM `ENTITY` e LEFT JOIN `META` m1 ON e.ID = m1.EntityID AND m1.meta_key = 'first name' LEFT JOIN `META` m2 ON e.ID = m2.EntityID AND m2.meta_key = 'last name' LEFT JOIN `META` m3 ON e.ID = m3.EntityID AND m3.meta_key = 'birthday'
- Coalescing:
SELECT e.* , MAX(IF(m.KEY= 'first name', m.VALUE, NULL)) as 'first name' , MAX(IF(m.KEY= 'last name', m.VALUE, NULL)) as 'last name' , MAX(IF(m.KEY= 'birthday', m.VALUE, NULL)) as 'birthday' FROM `ENTITY` e JOIN `META` m ON e.ID = m.EntityID
- Código:
SELECT e.* FROM `ENTITY` e WHERE e.ID = {whatever};
en PHP, crear un objeto marcador de posición a partir del resultadoSELECT m.* FROM `META` m WHERE m.EntityID = {whatever};
en PHP, bucle a través de resultados y adjuntar a objeto de entidad como:$e->{$result->key} = $result->VALUE
¿Qué es mejor en general, y para filtrar/clasificar?
preguntas relacionadas:
Si hubo una apuesta por el rendimiento y solo una oportunidad de disparar, apostaría por la unión múltiple. –
Necesita un 'GROUP BY e.ID' en las opciones 1 y 3. –
Mire [esta pregunta] (http://dba.stackexchange.com/questions/9466/most-performant-sql-query-needed) en dba.se – ConcernedOfTunbridgeWells