Вопрос дизайна базы данных - какое решение лучше? - PullRequest
2 голосов
/ 19 ноября 2010

Я использую Firebird 2.1 и ищу лучший способ решить эту проблему.

Я пишу приложение для календаря. Записи календаря разных пользователей хранятся в большой таблице Календаря. Каждая запись календаря может иметь набор напоминаний - только одно напоминание / запись.

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

Мне нужно постоянно запрашивать напоминания.

Какой вариант лучше?

A) Сохранять информацию напоминаний в таблице календаря (в этом случае я собираюсь запросить сотни тысяч записей для IsReminder = 1)

B) Создайте отдельную таблицу напоминаний, которая содержит только идентификатор записей календаря, для которых установлены напоминания, затем выполните запрос к двум таблицам с помощью операции JOIN (или, возможно, создайте для них представление)

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

Что вы думаете?

И еще один вопрос: таблица календаря будет содержать календарь нескольких пользователей, разделенных только полем UserID. Поскольку может быть только 4-5 пользователей, даже если я добавлю индекс в это поле, его избирательность будет очень плохой - что не хорошо для таблицы с сотнями тысяч записей. Есть ли обходной путь здесь?

Спасибо!

Ответы [ 3 ]

2 голосов
/ 19 ноября 2010

У всех трех вариантов есть свои преимущества и недостатки.Какой из них лучше, зависит от деталей, которые вы не предоставили.В общем, не беспокойтесь о выборе трех или четырех записей из ста тысяч, если настроенные вами индексы позволяют выбрать правильную стратегию поиска.Если вы не понимаете индексацию, вы, вероятно, будете в беде независимо от того, какой из трех вариантов вы сделаете.

Если бы это был я, я бы выбрал вариант B. Я бы также сохранил любые атрибуты.напоминания в таблице для напоминаний.

Будьте очень осторожны с тем, определяете ли вы событие только по EventId или по (UserId, EventId).Если вы выберете последний вариант, вам следует использовать составной первичный ключ для таблицы событий.Не беспокойтесь слишком о составных первичных ключах, особенно с Firebird.
Если вы объявляете составной первичный ключ, помните, что объявление (UserId, EventId) не будет иметь таких же последствий, как объявление (EventId, UserId).Они логически эквивалентны, но структура автоматически сгенерированного индекса будет отличаться в двух случаях.

Это, в свою очередь, повлияет на скорость запросов, таких как «найти все напоминания для данного пользователя».

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

И, если вы действительно хотите узнать влияние на производительность, попробуйте все три способа, загрузите сПроверьте данные и сделайте свои собственные тесты.

0 голосов
/ 19 ноября 2010

При выборе варианта (A) вы должны

  • предоставить индекс для "IsReminder" (или комбинированный индекс для IsReminder, UserId, независимо от того, что лучше всего соответствует вашим предполагаемым запросам)* убедитесь, что ваши запросы используют этот индекс

Вариант B предпочтительнее, чем A, если у вас есть более чем логический флаг для каждого напоминания для хранения (например, количество минут, которое пользователь должен уведомить дособытие).Вы должны, однако, сделать предположение, как часто в вашей программе вам нужно будет присоединиться к обеим таблицам.

Если можете, избегайте варианта C. Если вы не хотите сравнивать все три случая, я предлагаю начать с A или B, в соответствии с описанными обстоятельствами, и, вероятно, выбранное вами решение будет достаточно быстрымтак что вам не придется беспокоиться о других делах.

0 голосов
/ 19 ноября 2010

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

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

...