Эффективный дизайн базы данных MySQL для приложения, похожего на Tinder

Все методы в interface неявно public, независимо от того, объявляете ли вы это явно или нет. Подробнее см. В разделе интерфейсов Java Tutorials .

3
задан Arnaud Peralta 11 March 2019 в 14:09
поделиться

3 ответа

Есть несколько вещей, чтобы рассмотреть.

Во-первых, размер таблицы не очень интересен, если вы не знаете, какие типы запросов вам нужно выполнить. Как уже говорили другие, не нужно бояться таблиц с сотнями миллионов строк, и если вы запрашиваете индексируемые поля, вы, вероятно, можете масштабировать до миллиардов строк, не переходя к экзотическим решениям просто покупка большего и лучшего оборудования. Итак, решение, в котором 90% ваших запросов - это

select * from users where user_id not in (select interacted_user_id from interactions where interacting_user_id = $current_user) limit 10

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

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

Один из способов разделить ваши данные - это собрать «взаимодействия» по регионам. Это требует некоторых размышлений - вам, вероятно, не нужны «жесткие» границы, а скорее перекрывающиеся географии. Каждое место на карте может иметь несколько перекрывающихся «регионов», каждый со своей таблицей. Чем больше пользователей у вас в регионе, тем меньше у вас перекрывающихся кругов - у Манхэттена может быть 3 региона, у Гренландии может быть только 1. Ваш запрос затем просматривает таблицы для каждого перекрывающегося региона и объединяет пользователей, которые ранее не имели взаимодействовал с текущим пользователем.

0
ответ дан Neville Kuyt 11 March 2019 в 14:09
поделиться

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

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

Также вам не нужно хранить, когда людям нравится вместе.

РЕДАКТИРОВАТЬ: а почему бы не CHECKSUM () с обоими столбцами для хранения хеша для каждого отношения? Это будет легче.

РЕДАКТИРОВАТЬ 2: и не забывайте, что это приложение любви. И люди не совпадают со всеми, потому что у них есть сексуальная ориентация.

0
ответ дан Arnaud Peralta 11 March 2019 в 14:09
поделиться

Если человеку 1 не понравился человек 2, нет необходимости показывать человека 1 человеку 2. Даже если вы покажете его, они никогда не совпадут. Поэтому ваш расчет 1K x 1K = 1M немного завышен.

Однако, если вы все еще хотите иметь наборы лайков и дислайков для обоих пользователей, вы можете рассмотреть эту ужасную идею «сжатия» строк.

Представьте, что у вас есть последовательность, подобная этой:

| Person 1 | Person 2 |  Op       |
| -------- | -------- | --------- |
| 0001     | 1010     |  Dislike  |
| 0001     | 1011     |  Dislike  |
| 0001     | 1012     |  Dislike  |
| 0001     | 1013     |  Dislike  |
| 0001     | 1015     |  Like     |
| 0001     | 1017     |  Dislike  |
| 0001     | 1018     |  Dislike  |
| 0001     | 1019     |  Dislike  |
| 0001     | 1021     |  Like     |

Если у вас есть идентификаторы, следующие друг за другом, вы можете показать их как

| Person 1 | Person 2 |  Op       | N    |
| -------- | -------- | --------- | ---- |
| 0001     | 1010     |  Dislike  | 3    |
| 0001     | 1015     |  Like     | 0    |
| 0001     | 1017     |  Dislike  | 2    |
| 0001     | 1021     |  Like     | 0    |

где N - это максимальный идентификатор в последовательности ( например, 1010 + 3 = 1013). Если вы определите N как непоказанный tinyint, то максимально возможный размер последовательности может составить 255, то есть теоретически 255 последовательных дислайков / лайков можно сохранить как 1 запись.

И запрос будет примерно таким (представьте, что вы ищете идентификатор 1013):

SELECT a.* 
FROM (
    SELECT *
    FROM `table`
    WHERE person_1 = 0001
      AND person_2 >= (1013 - 255) -- 255 is a max size of a sequense 
      AND person_2 <= 1013
) a
WHERE a.person_2 <= 1013 AND a.person_2 + N >= 1013

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

| Person 1 | Person 2 |  Op       | N    |
| -------- | -------- | --------- | ---- |
| 0001     | 1010     |  Dislike  | 3    |

Но лично я бы пошел с этим и предпочел бы ваше текущее решение из-за его простоты.

ИЛИ как другой вариант, вы можете сжать таблицу таким образом

| Person 1 | Person 2 | Max Person 2 |  Op       |
| -------- | -------- | ------------ | --------- |
| 0001     | 1010     | 1013         |  Dislike  |
| 0001     | 1015     | 1015         |  Like     |
| 0001     | 1017     | 1019         |  Dislike  |
| 0001     | 1021     | 1021         |  Like     |
0
ответ дан Sergey Stativa 11 March 2019 в 14:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: