Модель базы данных EAV, запись списка в соответствии с поиском - PullRequest
0 голосов
/ 16 мая 2010

Я создаю динамическое приложение. У меня есть три таблицы: (стиль модели EAV)

  1. Предметы (ItemId, ItemName)
  2. Поля (FieldId, FieldName)
  3. Значения полей (ItemID, FieldId, Value)

Можете ли вы сказать мне, как написать ОДИН запрос, чтобы получить стартовые 20 записей из ВСЕХ элементов, где FieldId = 4 равно TRUE.

Ожидаемый результат:

Columns =>  ItemID | Name  | Field1 | Field2 |  Field3  
Each Row=>  ItemId | ItemName| Value1 | Value2 | Value3

Важные проблемы:

  1. Количество полей на единицу неизвестно
  2. Мне нужен один, чтобы написать ОДИН запрос.
  3. Запрос будет работать на 100K записей, поэтому производительность беспокоит.
  4. Я использую MySQL 5.0, поэтому нужно решение для MYSQL

Должен ли я денормализовать таблицы, если приведенный выше запрос вообще невозможен? Любой совет?

1 Ответ

1 голос
/ 22 июля 2010

Дизайн EAV денормализован . То есть это нереляционный дизайн. Нет правила нормализации, которое привело бы вас к использованию дизайна EAV.

SQL требует, чтобы вы знали столбцы при написании запроса, а также чтобы в каждой строке набора результатов были одинаковые столбцы. В случае EAV единственным решением, если вы не знаете, сколько полей на элемент, является выборка их в виде строк, а не столбцов.

SELECT i.ItemID, i.ItemName, f.FieldName, v.Value
FROM Items i
JOIN FieldsValues v4 ON (v4.ItemID, v4.FieldID, v4.Value) = (i.ItemID, 4, TRUE)
JOIN FieldsValues v ON i.ItemID = v.ItemID
JOIN Fields f ON v.FieldID = f.FieldID;

Вы должны обработать строки в вашем приложении. Например, с PHP:

<?php

$pdo = new PDO(...);
$sql = "...above query...";

$collection = array();

foreach ($pdo->query($sql) as $row) {
  $id = $row["ItemID"];
  if (!array_key_exists($id, $collection)) {
    $collection[$id] = new stdClass();
    $collection[$id]->Name = $row["ItemName"];
  }
  $collection[$id]->$row["FieldName"] = $row["Value"];
}

Теперь у вас есть массив объектов, и каждый объект соответствует элементу из базы данных. Каждый объект имеет свой соответствующий набор полей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...