В моем приложении Rails у меня есть множество таблиц базы данных, содержащих пользовательские данные. Некоторые из этих таблиц в некоторых случаях содержат много строк (до 500 000 строк на пользователя) и часто запрашиваются. Всякий раз, когда я запрашиваю любую таблицу для чего-либо, user_id текущего пользователя находится где-то в запросе - либо напрямую, если таблица имеет прямую связь с пользователем, либо через соединение, если они связаны через некоторые другие таблицы.Чтобы нормализовать или не нормализовать user_ids
Должен ли я денормализовать user_id и включать его в каждую таблицу для повышения производительности?
Вот один пример:
- Адрес относится к пользователю, и имеет user_id
- Конверт принадлежит пользователю, и имеет user_id
- AddressesEnvelopes присоединяется адрес и конверта, так он имеет envelope_id и address_id - он не имеет user_id, но может попасть в него через конверт или адрес (который должен принадлежать одному пользователю).
Одним из распространенных дорогостоящих запросов является выбор всех АдресовEnvelop для конкретного пользователя, что я мог бы выполнить, присоединившись к любому Адресу или Конверту, хотя мне ничего не нужно из этих таблиц. Или я мог бы просто дублировать идентификатор пользователя в этой таблице.
Вот другой сценарий:
- Письмо принадлежит пользователю, и имеет user_id
- этом получатель принадлежит к письму, и имеет letter_id
- RecepientOption принадлежит этом получатель, и имеет recepient_id
Имеет смысл дублировать user_id как у получателя, так и получателя Вариант, хотя я всегда мог добраться до него, пройдя через ассоциации, через Письмо?
Некоторые примечания:
- Там никогда никаких предметов, которые распределяются между пользователями. Целая иерархия связанных объектов всегда принадлежит к тому же пользователю.
- Пользовательский пользователь объектов никогда не изменяется.
- Производительность базы данных важна, потому что это приложение, интенсивно использующее данные. Существует много запросов и много таблиц.
Так что я должен включать user_id в каждой таблице, так что я могу использовать его при создании индексов? Или это будет плохой дизайн?
Спасибо, Роланд. Это именно то, о чем я думал.Возможно, денормализация была неправильным словом для использования, поскольку я фактически не денормализую данные из таблицы пользователя в другие таблицы, просто включив user_id в качестве ключа в таблице, где можно получить через user_id через другой ключ (например, в пример address_envelopes, где вы можете получить user_id через адрес или конверт). Кластеризованное индексирование и разбиение данных между таблицами/машинами пользователем звучит как отличная идея! –