Вопрос дизайна базы данных - который является лучшим решением?
-
26-09-2019 - |
Вопрос
Я использую Firebird 2.1, и я ищу лучший способ решить эту проблему.
Я пишу календаряное приложение. Записи календаря разных пользователей хранятся в большом календарном столе. Каждая запись календаря может иметь набор напоминаний - только одно напоминание / запись.
Статистически, календарный стол может расти до сотен тысяч рекордов со временем, а намного меньше напоминания.
Мне нужно запросить напоминания на постоянной основе.
Какой лучший вариант?
А) Храните информацию о напоминании в таблице календаря (в этом случае я собираюсь запрашивать сотни тысяч записей для Isreminder = 1)
B) Создание отдельной таблицы напоминаний, которая содержит только идентификатор записей календаря, которые накладывают напоминания, затем запрашивают две таблицы с операцией присоединения (или, возможно, создайте на них представление)
C) Я могу хранить всю информацию о напоминаниях в таблице напоминаний, а затем запрашивать только эту таблицу. Недостатная связь состоит в том, что некоторая информация должна быть дублирована в обеих таблицах, как для того, чтобы показать напоминание, мне нужно будет знать и хранить начало события в таблице напоминаний - таким образом я поддерживаю две таблицы с одинаковыми значениями.
Как вы думаете?
И еще один вопрос: таблица календаря будет содержать Calender множества пользователей, разделенных только полем пользователя. Поскольку могут быть только 4-5 пользователей, даже если я положил индекс на это поле, его селективность будет очень плохой - что не хорошо для стола с сотнями тысяч записей. Здесь здесь обходной путь?
Спасибо!
Решение
Есть преимущества и недостатки для всех трех вариантов. Whis можно лучше, зависит от деталей, которые вы не предоставили. В целом, не слишком беспокоитесь о выборе трех или четырех записей из ста тысяч, при условии, что указанные вами индексы позволяют правильной извлеченной стратегии. Если не понимать индексацию, вы, вероятно, будете в беде, независимо от того, какой из трех вариантов вы делаете.
Если бы это было я, я бы пошел с выбором B. Я бы также хранил какие-либо атрибуты напоминания в таблице для напоминаний.
Будьте очень осторожны о том, определяете ли вы событие, что EventiD Oney или (UsiliD, EventiD). Если вы выберете последнее, он не замечает вас, чтобы использовать первичный ключ соединения для таблицы событий. Не волнуйтесь слишком много о составных первичных ключах, особенно с Firebird.
Если вы объявляете первичный ключ соединения, осознайте, что объявление (UsiliD, EventiD) не будет иметь тех же последствий, что и объявление (EventiD, usive). Они логически эквивалентны, но структура автоматически сгенерированного индекса будет отличаться в двух случаях.
Это в свою очередь, повлияет на скорость запросов, таких как «Найти все напоминания для данного пользователя».
Опять же, если бы это был я, я бы избегал выбора C. Введение вредных избыточности в схему несет на себя ответственность за некоторые очень тщательное программирование, когда вы идете на обновление данных. В противном случае вы можете в конечном итоге с базой данных хранится противоречивые версии того же факта в разных местах базы данных.
И, если вы действительно хотите узнать эффект на выполнении перфорации, попробуйте все три способа, нагрузка с тестовыми данными и выполните свои ориентиры.
Другие советы
Я думаю, вам нужно создать реалистичные, поддельные пользовательские данные и измерить разницу с некоторыми типичными запросами, которые вы ожидаете запустить.
Индексирование, оптимизация запросов и типы результатов запроса, которые вам нужны, может иметь большое значение, поэтому нелегко сказать, что лучше, не зная большего.
При выборе варианта (а) вы должны
- Укажите индекс на «Isreminder» (или объединенный индекс на ISREMINDER, UserID, что все, что подходит для ваших намеченных запросов)
- Убедитесь, что ваши запросы используют этот индекс
Опция B предпочтительнее над A Если у вас есть больше, чем булева для каждого напоминания для хранения (например, количество минут пользователь должен быть уведомлен до события). Однако вы должны догадаться, как часто в вашей программе вам придется присоединиться к обею таблицам.
Если вы можете избегать вариантов C. Если вы не хотите прозоктовать все три случая, я предлагаю начать с A или B, в соответствии с описанными обстоятельствами, и, вероятно, решение, которое вы выбираете, будет достаточно быстрым, так что вы не будете достаточно быстро должны беспокоиться с другими случаями.