Организация и оптимизация таблиц MySQL (Rails) - PullRequest
3 голосов
/ 10 марта 2011

За последние несколько месяцев я изучал Ruby on Rails, не имея опыта программирования. В последнее время я думал об оптимизации базы данных и организации таблиц. Я знаю, что есть прекрасные книги на эту тему, но я обычно учусь на примере / по ходу дела.

Вот гипотетическая ситуация:

Допустим, я создаю социальную сеть для нишевого сообщества с 250 000 участников (пользователей). Пользователи имеют возможность посещать мероприятия. Допустим, есть 50000 событий прошлого / настоящего / будущего. Подобно событиям в Facebook, пользователь может посещать любое количество мероприятий, и на мероприятии может присутствовать любое количество участников.

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

Однако ни одно из этих решений не кажется идеальным. На странице профиля пользователя я хочу отобразить список событий, с которыми они связаны, что потребовало бы сканирования 50000 строк событий для идентификатора пользователя указанного пользователя, если я включу столбец «участников» в таблицу событий. Аналогично, на странице события я хочу отобразить список участников для события, для которого потребуется сканирование 250000 строк пользователя для идентификатора события указанного события, если я включу столбец «события» в таблицу пользователей.

Вариант 3 - создать третью таблицу, содержащую информацию о посетителе для каждого события, но я не понимаю, как это решило бы какие-либо проблемы.

Это не проблемы? Rails облегчает доступ ко всей этой информации, но, думаю, меня беспокоит масштаб. Вполне возможно, что я недооцениваю скорость и вычислительную мощность современных баз данных / серверов / и т. Д. Сколько времени потребуется для сканирования 250 000 пользовательских строк на предмет определенных идентификаторов событий - 10 мс? 100мс? 1,000ms? Я думаю, это не так уж плохо. Я просто слишком обдумал это?

Ответы [ 3 ]

3 голосов
/ 10 марта 2011

Это типичные отношения «многие ко многим» между пользователями и событиями.

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

Таким образом, он будет иметь как минимум userID и eventID как внешние ключи для таблицы User и Event.

Добавление индексов в эти 2 поля, вероятно, будет полезно для ваших запросов, поскольку вы планируете иметь миллионы строк.

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

Загвоздка в том, что в каждой строке есть информация о «посетителях». Кто посещал (userID), что посещал (eventID), когда он прибыл, сколько потратил во время и т. Д. Вы не хотите помещать эту информацию ни в таблицу User, ни в таблицу Event.

Поскольку вы беспокоитесь о производительности, я добавлю пример того, как база данных будет искать конкретный запрос. Допустим, мы хотим найти всех пользователей, которые посещают (или планируют) мероприятие «U2 концерт в Афинах, июль 2011 года» и имеют тот же день рождения, что и я.

database plan:
1. use eventTitle index in table Event 
     to find that the event has id 47519 
   (good for us that we have created such an index).
2. use eventID index in table Attends 
     to find all (469) userids that have attended eventid 47519.
3. use the userid index in table User
     to find all the info of the 469 users.
4. search the info (birthdate) from those
     to keep only those (3) that have birthday July 24th.
     (we have not created any index that can be used here)

Таким образом, база данных обращается к дискам только для поиска индексов и чтения необходимых нам данных. Не читать все данные и искать в них.

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

0 голосов
/ 11 июля 2013

Старый вопрос, но я добавляю детали, пока я ищу другие вещи.

В Rails это обрабатывается с помощью предложения has_and_belongs_to_many в модели, которое создает таблицу разрешения многих ко многим.для тебя.Документация здесь: http://guides.rubyonrails.org/association_basics.html

С объектом разрешения база данных фактически не сканирует всю таблицу в поисках информации, она использует индекс b-дерева для поиска нужных строк - отсюдамногие-ко-многим напрямую решают проблему с производительностью, которую вы поднимаете.

0 голосов
/ 10 марта 2011

"На странице профиля пользователя я хочу отобразить список событий, с которыми они связаны, что потребовало бы сканирования 50000 строк событий для идентификатора пользователя указанного пользователя, если я включу столбец" посетители "в таблицу событий . "

Было бы необходимо просканировать 50 000 строк событий, если бы каждый идентификатор пользователя не был уникальным ключом, что я, безусловно, надеюсь. Если каждый идентификатор пользователя является уникальным ключом, то это быстро. Аналогично таблица событий: каждое событие будет иметь уникальный идентификатор, который также является его уникальным ключом.

Вы должны сделать эти идентификаторы уникальными ключами, иначе вы в глубоких кроссовках.

- Пит

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