MySQL: разделение одной таблицы на несколько таблиц (те же столбцы) для повышения производительности?

Это вопрос о производительности, а не о возможных решениях.

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

ItemA - id, fld1, fld2
ItemB - id, fld1, fld3, fld4
ItemC - id, fld1, fld3, fld5
....

Теперь необходимо управлять пользовательским инвентарем, то есть есть у пользователя предмет или нет. Один из вариантов использует одну таблицу:

Inventory - category_id, item_id, user_id

category_id отличается для строк ItemA, ItemB,..., и именно так мы различаем.

Второй вариант - иметь:

InventoryA - item_id, user_id
InventoryB - item_id, user_id
...

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

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

В настоящее время система использует MySQL и движок InnoDB. Есть около 10 категорий, но ожидается, что в ближайшем будущем их станет несколько десятков. Самая большая категория содержит > 200 000 элементов, а большинство из них – > 10 000 элементов. Единая таблица инвентаризации содержит > 10 миллионов строк и, как ожидается, станет НАМНОГО больше по мере присоединения большего числа пользователей.

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

Если у вас есть личный опыт решения подобной проблемы, поделитесь им.

Спасибо


person Colnector    schedule 04.12.2009    source источник
comment
Может ли один элемент принадлежать (использоваться) многим пользователям?   -  person Damir Sudarevic    schedule 05.12.2009
comment
Да, Дамир, это отношения «многие ко многим».   -  person Colnector    schedule 05.12.2009


Ответы (2)


Нормализация базы данных обычно лучше для производительности и удобства сопровождения.

При таком подходе создается таблица Items, имеющая отношение 1:1 к ItemA, ItemB и т. д. Затем можно создать таблицу Inventory, имеющую отношение к базовой таблице Items.

Согласно документации, InnoDB поддерживает строки блокировки уровня, поэтому нет необходимости использовать несколько таблиц для предотвращения взаимоблокировок.

person Andomar    schedule 04.12.2009
comment
Спасибо, Андомар, за ответ. ИМХО, однако, то, что вы предлагаете, на самом деле было бы очень плохой идеей, которая еще больше снизит производительность. В настоящее время реализовано первое решение, которое я представил. Каждый запрос в базе данных относится только к одной из категорий, и я действительно не могу понять, как добавление дополнительной таблицы Items улучшит производительность. Нормализация — хорошая концепция, но здесь вопрос касается практических последствий для производительности. Да, InnoDB поддерживает блокировки на уровне строк, но я боюсь не взаимоблокировок, а снижения производительности. - person Colnector; 05.12.2009
comment
@Colnector: добавление базовой таблицы позволяет вам установить отношение внешнего ключа между inventory и item - person Andomar; 05.12.2009
comment
Да @Andomar, я понимаю это, но я действительно не понимаю, как это помогает мне в том, о чем я спрашиваю. В настоящее время у меня есть инвентарь (category_id, item_id, user_id), и с вашим предложением у меня будет инвентарь (item_id, user_id), НО мне придется ПРИСОЕДИНЯТЬСЯ к новой таблице Item для КАЖДОГО И КАЖДОГО запроса. Это снизит производительность. - person Colnector; 05.12.2009
comment
@Коллектор. Глупо становится, когда ты спрашиваешь ответы, а значит, не знаешь, а потом споришь с ответом того, кто знает предмет. Есть ли у вас какие-либо доказательства (не мысли), что денормализованное работает быстрее, чем нормализованное. - person PerformanceDBA; 17.01.2011

Вот мой взгляд на эту историю, надеюсь, что это немного поможет.

  • Таблица элементов имеет поля, общие для всех элементов.
  • Таблицы категорий (A, B, C) имеют поля, характерные для каждой из них.
  • У одного пользователя много элементов, один элемент может использоваться многими пользователями.

    inventory_model_01
person Damir Sudarevic    schedule 04.12.2009
comment
Спасибо, Дамир, это похоже на то, что Андомар предложил выше. Пожалуйста, смотрите мой комментарий там. Хороший набросок :) - person Colnector; 05.12.2009