Стол БД получает слишком много данных - нужно другое решение - PullRequest
3 голосов
/ 03 октября 2010

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

Каждый отмеченный эпизод создает одну запись в таблице БД (с user_id, show_id и episode_id).
ThisТаблица теперь содержит более 600 000 строк и растет очень быстро!

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

Мои мысли оновое решение:

Таким образом, вместо:

user_id | show_id | episode_id  
1 ....... 123 ......7675  
1 ....... 123 ......7676   
1 ....... 123 ......7677  
1 ....... 456 ......5678  
1 ....... 456 ......5679  
1 ....... 456 ......5680  

я мог бы сделать это:

user_id | show_id | episode_ids  
1 ....... 123 ......7675,7676,7677  
1 ....... 456 ......5678,5679,5680

Тогда мне придется разбить строку на массив и использовать array.include? (Some-id) .
Это должно облегчить работу базы данных, но для Ruby будет гораздо более тяжелый код массива.

Я на правильном пути?Или кто-нибудь может придумать лучшее решение?

Ответы [ 4 ]

13 голосов
/ 03 октября 2010

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

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

  • Определите, действительно ли является проблемой
  • Найдите причину этого, используя соответствующие инструменты
  • Проверьте возможные решения внепроизводственная среда.

600 тыс. строк НИЧЕГО (в таблице с тремя целыми числами).В самом деле.Это может вписаться в оперативную память даже на самых маленьких серверах.Запросы к таблице из оперативной памяти должны быть настолько быстрыми, что об этом не стоит беспокоиться.

Если вы прошли шаг 1 (действительно есть проблема), задайте дополнительные вопросы, содержащие всю вашу соответствующую схему, точные запросы,объяснить планы и сроки.

2 голосов
/ 03 октября 2010

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

  • Является ли источник вашей проблемы действительно базой данных?Или это какая-то другая система (сеть, веб-сервер, рельсы и т. Д.)?
  • Что является приемлемым с точки зрения времени ответа на запрос?Найдите конкретные числа, которым база данных должна придерживаться при любых обстоятельствах.
  • Какие запросы становятся медленнее?Возможно, у вас медленные, неэффективные запросы, которые можно реорганизовать.Составьте план запроса, посмотрите, что делает оптимизатор.
  • Правильно ли вы используете индексы?
  • Настройте свой экземпляр mysql.С настройкой вы можете многого достичь.
  • Обратите внимание, что вы можете что-то делать на аппаратной стороне (получить больше памяти, увеличить скорость дисков и т. Д.)Есть любые
  • Если все вышеперечисленное выполнено, вы все равно можете сделать шард.Это добавляет сложности вашему приложению, но позволит вам в достаточной степени масштабировать вашу систему без особых усилий.
  • В конечном итоге вы можете прийти к выводу, что вы должны использовать «действительно масштабируемый» распределенный ключ./ значение хранилища (nosql).Но до 600 тыс. Строк еще далеко, пока вы не достигнете этой точки.

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

1 голос
/ 03 октября 2010

Вот как я бы структурировал таблицы:

USERS
userid INTEGER PRIMARY KEY 
username text/varchar/whatever

SHOWS
showid INTEGER PK
showname   varchar or nvarchar or text  [depending on what database I was using]
etc etc


EPISODES
episodeid INTEGER PK
showid    INTEGER  FK references SHOWS   [index this field]
ordinal   DECIMAL   [indicates which episode  -- DECIMAL makes it easier to insert later an episode you overlooked] 
episodename text/varchar/nvarchar whatever   
etc etc

SEENIT
id  INTEGER AUTOINCREMENT  PK
userid  INTEGER    foreign key ref USERS
episodeid  INTEGER foreign key ref EPISODES

Вы можете разместить альтернативный уникальный составной индекс (userid, episodeid) или использовать отдельные индексы, один для идентификатора пользователя, другой для эпизода.Я бы, наверное, пошел с последним.

0 голосов
/ 03 октября 2010

Я бы придерживался нормализованных данных.Это больше похоже на проблему оптимизации запросов.Имейте в виду, что mysql (при условии, что вы используете его) использует только один индекс на запрос, и вы можете повысить производительность, настроив составной индекс.Также используйте оператор EXPLAIN в браузере запросов mysql.Больше информации здесь: http://dev.mysql.com/doc/refman/5.1/en/explain.html

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