Структура таблицы MySQL: несколько атрибутов для каждого элемента

Я хотел спросить вас, какой подход лучше всего подходит для создания моей структуры базы данных MySQL в следующем случае.

У меня есть таблица с items, которую не нужно описывать, так как единственное важное поле здесь — это ID.

Теперь я хотел бы иметь возможность назначать некоторые атрибуты каждому элементу - конечно, по его ID. Но я точно не знаю, как это сделать, так как хотел бы, чтобы он был динамическим (поэтому мне не нужно изменять структуру таблицы, если я хочу добавить новый тип атрибута).

Что я думаю

Я думаю - и, на самом деле, это структура, которая у меня есть прямо сейчас - что я могу сделать таблицу items_attributes со следующей структурой:

+----+---------+----------------+-----------------+
| id | item_id | attribute_name | attribute_value |
+----+---------+----------------+-----------------+
|  1 |       1 | place          | Barcelona       |
|  2 |       2 | author_name    | Matt            |
|  3 |       1 | author_name    | Kate            |
|  4 |       1 | pages          | 200             |
|  5 |       1 | author_name    | John            |
+----+---------+----------------+-----------------+

Я привел данные в качестве примера, чтобы вы увидели, что эти атрибуты могут повторяться (это не отношение 1 к 1).

Проблема с этим подходом

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

Кроме того, может быть, потому, что я не эксперт по MySQL, каждый раз, когда я хочу выполнить поиск и найти «те элементы, у которых« место »=« Барселона »И« автор_имя »=« Джон »», мне в конечном итоге приходится делать несколько JOIN для каждого условия.

Повторяя предыдущий пример, мой запрос будет выглядеть так:

SELECT * 
FROM items its 
JOIN items_attributes attr 
   ON its.id = attr.item_id 
      AND attr.attribute_name = 'place' 
      AND attr.attribute_value = 'Barcelona' 
      AND attr.attribute_name = 'author_name' 
      AND attr.attribute_value = 'John';

Как видите, это ничего не вернет, так как attribute_name не может иметь два значения одновременно в одной строке, а условие OR не будет тем, что я ищу, поскольку элементы ДОЛЖНЫ иметь оба значения атрибутов, как указано.

Таким образом, единственная возможность состоит в том, чтобы сделать JOIN в одной и той же повторяющейся таблице для каждого условия поиска, что, я думаю, будет очень медленным, когда есть много терминов для поиска.

что бы я хотел

Как я уже сказал, я хотел бы иметь возможность сохранять динамические типы атрибутов, поэтому достаточно добавить новый ввод в «attribute_name» без необходимости добавления нового столбца в таблицу. Кроме того, поскольку они представляют собой отношения 1-N, их нельзя поместить в таблицу «элементы» в качестве новых столбцов.

Если структура, по вашему мнению, единственная, которая может удовлетворить мои интересы, если бы вы могли осветить некоторые идеи, чтобы поисковые запросы не были тонной JOIN, это тоже было бы здорово.

Я не знаю, сложно ли это получить, так как я до сих пор ломал голову и не нашел решения. Надеюсь, вы, ребята, можете помочь мне с этим!

В любом случае, спасибо за ваше время и внимание!

С уважением.


person Unapedra    schedule 20.05.2015    source источник


Ответы (2)


Вы думаете в правильном направлении, в направлении нормализации. Обычной для вас в базе данных является пятая нормальная форма (или шестая, даже ). Stackoverflow по этот вопрос.

Атрибут таблицы:

+----+----------------+
| id | attribute_name | 
+----+----------------+
|  1 |          place |
|  2 |    author name |
|  3 |          pages |
+----+----------------+

Атрибут элемента таблицы

+--------+----------------+
| item_id|   attribute_id | 
+--------+----------------+
|      1 |              1 |
|      2 |              1 |
|      3 |              2 |
+--------+----------------+

Таким образом, для каждого свойства объекта (в данном случае элемента) вы создаете новую таблицу и называете ее соответствующим образом. Это требует большого количества объединений, но ваша база данных будет очень гибкой и организованной. Удачи!

person marijnz0r    schedule 20.05.2015
comment
это не помогает, потому что в этом случае у него есть эти записи в таблице author_name | Джон и author_name | Кейт и собственно страницы | 200 и вы должны добавить еще одну таблицу для нормализации этой таблицы - person The Reason; 20.05.2015
comment
Да, это то, что я имел в виду с предпоследним предложением. В этом случае он должен добавить таблицу ItemPages и вставить (1200) в качестве записи. - person marijnz0r; 20.05.2015
comment
Спасибо за ваше время и ответ! Я вижу, что все решения будут указывать на одно и то же направление, как вы сказали, на нормализацию. Я бы не хотел иметь столько столов, сколько мне кажется, но если это лучший подход, то нет оправдания! Я посмотрю, придет ли кто-нибудь с другим подходом к обзору. Спасибо за ваше время и ссылки! - person Unapedra; 20.05.2015

По моему мнению, это должно быть что-то вроде этого, я знаю, что таблиц много, но на самом деле это нормализует вашу БД enter Может быть, поэтому, потому что я не могу понять, где вы берете свой столбец att_value и что должно содержать эти столбцы

person The Reason    schedule 20.05.2015
comment
Спасибо за Ваш ответ! Столбцы значений — это свойства элемента, динамически устанавливаемые пользователем. Итак, пользователь пишет, что автор — Джон и Кейт, а место — Барселона. Но пользователь должен иметь возможность написать произвольное поле, такое как, например, «погода» и написать в нем «облачно» (я пишу глупый пример, но чтобы вы знали, откуда они берутся). Именно по этой причине мне нужно, чтобы они были динамичными. - person Unapedra; 20.05.2015