2010-06-12 2 views
0

Недавно я столкнулся с довольно сложной проблемой, и, оглядев много, я не смог найти решение. Я нашел ответы на свои вопросы много раз, прежде чем на stackoverflow.com, поэтому я решил опубликовать здесь.2-столбец с двумя внешними ключами. Вопрос о производительности/дизайне

Так что я делаю систему Managment пользователя/группы для веб-проекта, и я хранить все соответствующие данные в базу данных PostgreSQL. Эта система опирается на три таблицы:

  1. ПОЛЬЗОВАТЕЛЕЙ (содержит первичный ключ «user_id»)
  2. ГРУППЫ (содержит первичный ключ «GROUP_ID»)
  3. GROUP_USERS

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

  1. User_ID
  2. GROUP_ID

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

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

Должен ли я придерживаться мое текущее решение, хранить, разделенных запятыми значений в столбце в ПОЛЬЗОВАТЕЛЕЙ столе или есть другое решение, я должен быть в курсе. Я ищу наилучшую производительность. Эта таблица может потенциально (но не обязательно или обычно) запрашиваться несколько сотен раз при загрузке одной страницы.

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

EDIT: Другими словами, использование комбинированного первичного ключа и двух внешних ключей в одной таблице с двумя столбцами отрицательно влияет на производительность, а не наоборот, из-за размера сгенерированного индекса?

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

Спасибо!

ответ

1

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

Мое предложение состоит в том, что у вас должен быть индекс первичного ключа в ПОЛЬЗОВАТЕЛЯх 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

Я установил таблицы так, как вы предлагали. Я считаю, что, скорее всего, я проверю, есть ли пользователь в данной группе или нет, а не наоборот. Ваш ответ заставляет меня чувствовать себя увереннее, что я делаю это правильно, поэтому я рассматриваю этот вопрос. Спасибо вам снова. – Emanuel

0

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

+0

Ну, да. Я не совсем уверен, как поставить свой вопрос на слова, может быть, я просто смущен. ;) Мой вопрос скорее, если это решение, о котором вы только что упоминали, будет иметь негативное влияние на производительность, а не на противоположное. Я отредактирую главный пост, чтобы это стало более ясным. Благодарим за быстрый ответ! – Emanuel

+0

Каждый индекс оказывает некоторое негативное влияние на производительность вставки, обновления и удаления, так как каждое изменение данных требует дополнительной записи ввода-вывода для обновления каждого индекса, но независимо от того, сколько индексов вы добавите, это может оказать положительное влияние на Read потому что, если есть индекс, который можно использовать для поиска нужной записи (ов), это значительно сократит количество Read IO, необходимых для доступа к данным. –

Смежные вопросы