Какова наилучшая производительность для получения результатов MySQL EAV в виде реляционной таблицы

Я хочу извлекать результаты из таблиц EAV (значение атрибута объекта) или, более конкретно, таблиц метаданных объекта (например, wordpress wp_posts и wp_postmeta ) как «красиво отформатированная реляционная таблица », для выполнения некоторой сортировки и / или фильтрации .

Я нашел несколько примеров того, как форматировать результаты в запросе (в отличие от написания двух запросов и объединения результатов в коде), но я хотел бы знать «наиболее эффективный» метод для этого, особенно для больших наборов результатов.

И когда я говорю «наиболее эффективный», я имею в виду что-то вроде следующих сценариев:

Получить все сущности с фамилией, например XYZ

Вернуть список сущностей, отсортированных по дате рождения


например. превратите это:

** 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

в это:

** 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

, чтобы я мог сортировать или фильтровать по любому из мета-полей.


Я нашел несколько предложений здесь , но я не могу найти обсуждение того, что работает лучше.

Параметры :

  1. GROUP_CONCAT :
    ВЫБРАТЬ 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
    
  2. Множественное объединение :
    ВЫБЕРИТЕ e. *, M1.VALUE как 'имя', m2.VALUE как 'фамилию', m3.VALUE как 'день рождения'
    ОТ `ENTITY` e
    LEFT JOIN `META` m1
    НА e.ID = m1.EntityID И m1.meta_key = 'имя'
    LEFT JOIN `META` m2
    НА e.ID = m2.EntityID И m2.meta_key = 'фамилия'
    LEFT JOIN `META` m3
    НА e.ID = m3.EntityID И m3.meta_key = 'birthday'
    
  3. Объединение :
    ВЫБЕРИТЕ e. *
     , МАКС (ЕСЛИ (m.KEY = 'имя', m.VALUE, NULL)) как "имя"
     , MAX (IF (m.KEY = 'фамилия'; m.VALUE, NULL)) как 'фамилия'
     , MAX (IF (m.KEY = 'birthday'; m.VALUE, NULL)) как 'день рождения'
    ОТ `ENTITY` e
    ПРИСОЕДИНЯЙТЕСЬ к `META` m
    НА e.ID = m.EntityID
    
  4. Код :
    ВЫБЕРИТЕ e. * FROM `ENTITY` e WHERE e.ID = {any};
    
    в PHP создайте объект-заполнитель из результата
     SELECT m. * FROM `META` m WHERE m.EntityID = {any};
    
    в PHP, пропустите результаты и прикрепите к объекту сущности, например: $ e -> {$ result-> key} = $ result-> VALUE

Что лучше в целом и для фильтрации / сортировки ?

Связанные вопросы:

  1. Привязка результатов EAV
  2. Как повернуть объект MySQL

14
задан Community 23 May 2017 в 10:34
поделиться