2-колоночная таблица с двумя внешними ключами. Производительность / дизайн вопрос - PullRequest
0 голосов
/ 12 июня 2010

Недавно я столкнулся с довольно сложной проблемой, и, много раз осмотревшись, не смог найти решения.Я уже много раз находил ответы на свои вопросы на stackoverflow.com, поэтому я решил опубликовать здесь.

Итак, я создаю систему управления пользователями / группами для веб-проекта, и я 'хранит все связанные данные в базе данных postgreSQL.Эта система использует три таблицы:

  1. USERS (содержит первичный ключ "USER_ID")
  2. GROUPS (содержит первичный ключ "GROUP_ID")
  3. GROUP_USERS

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

  1. USER_ID
  2. GROUP_ID

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

Теперь оба столбца являются внешними ключами, и я хочу также сделать их составным первичным ключом, так как каждая комбинация USER_IDи GROUP_ID должен быть уникальным.Но теперь я застрял с тем, что кажется большим количеством индексов и отношений с очень маленькой таблицей, содержащей только цифры.В конце я хочу, чтобы эта таблица была максимально быстрой, даже если она содержит десятки тысяч строк.Размер на диске не должен быть проблемой, так как в любом случае это просто все числа, но довольно глупо иметь полноразмерный индекс, ссылающийся на меньшую таблицу.

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

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

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

EDIT2: разъяснения.

Спасибо!

Ответы [ 2 ]

1 голос
/ 12 июня 2010

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

Я предлагаю вам иметь индекс первичного ключа в USERS по USER_ID, индекс первичного ключа в GROUPS по GROUP_ID и еще два индекса в GROUP_USERS. Один из индексов в GROUP_USERS должен быть либо парой (USER_ID, GROUP_ID), либо парой (GROUP_ID, USER_ID). Второй индекс должен соответствовать полю, которое осталось на втором месте в последнем определенном индексе.

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

  1. Запрос, в какие группы входит определенный пользователь.
  2. Запрос о том, какие пользователи входят в определенную группу.

Если 1 больше 2, то ваш первичный ключ должен быть (USER_ID, GROUP_ID), в противном случае (GROUP_ID, USER_ID).

0 голосов
/ 12 июня 2010

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

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