Postgres: дизайн таблицы для сохранения связанных пар - PullRequest
0 голосов
/ 06 апреля 2020

Я использую Postgres.

Имея чат-бота, мне нужно создать таблицу для хранения матчей:

A в паре с B и, следовательно, B в паре с A.

Я думал о том, чтобы создать таблицу типа:

CREATE TABLE matches (user_a INT, user_b INT);

И сохранить пару раз как:

INSERT INTO matches (1, 2);

Или дважды как:

INSERT INTO matches (1, 2);
INSERT INTO matches (2, 1);

Мне нужно будет запросить таблицу также только с одним столбцом, чтобы проверить пользователя «1»

В первом случае мне нужно будет использовать:

SELECT * FROM matches WHERE user_a=1 or user_b=1;

Во втором случае я могу запрос только с помощью:

SELECT * FROM matches WHERE user_a=1; 

Поскольку сохраняются обе стороны совпадения.

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

SELECT * FROM users LEFT JOIN matches ON matches.user_a=users.user_id OR matches.user_b=users.user_id;

Во втором случае я могу избежать операции ИЛИ:

SELECT * FROM users LEFT JOIN matches ON matches.user_a=users.user_id;

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

1 Ответ

1 голос
/ 06 апреля 2020

В общем, OR убивает JOIN производительность. Оптимизатору гораздо сложнее оптимизировать. Это говорит о том, что хранение двух строк в таблице, а не 1, часто приводит к повышению производительности - возможно, нелогично, поскольку это удваивает значения данных.

Тем не менее, если вы сделаете go для Более краткая форма, есть вещи, которые вы можете сделать, например:

SELECT u.*, m.*
FROM users u LEFT JOIN
     (matches m CROSS JOIN LATERAL
      (VALUES (m.user_a), (m.user_b)
      ) v(user_id)
     )
     ON v.user_id = u.user_id ;

Для этого следует использовать индекс users(user_id). Тем не менее, ваша версия или IN должна использовать индекс для этой таблицы. Но гораздо сложнее использовать индекс для matches.

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