#sql #database #performance #schema #structure
#sql #База данных #Производительность #схема #структура
Вопрос:
Представьте, что у нас есть веб-сайт, на котором пользователи могут читать статьи, просматривать фотографии, смотреть видео и многое другое. Каждый «элемент» может быть прокомментирован, поэтому нам нужно место для сохранения этих комментариев где-нибудь. Давайте обсудим возможности хранения для этого случая.
Распределенное решение
Очевидно, что мы можем создать отдельные таблицы для каждого «элемента», чтобы у нас были такие таблицы, как:
CREATE TABLE IF NOT EXISTS `article_comments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`createdBy` int(11) DEFAULT NULL,
`createdAt` int(11) DEFAULT NULL,
`article` int(11) DEFAULT NULL,
`content` text,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
а затем, очевидно photo_comments
, video_comments
, и так далее. Преимущества этого способа заключаются в следующем:
- мы можем указать внешний ключ для каждой таблицы «item»,
- база данных разделена на логические части.
- с экспортом таких данных проблем нет.
Недостатки:
- много столов
- вероятно, его трудно поддерживать (добавление полей и т.д.).
Централизованное решение
С другой стороны, мы можем объединить все эти таблицы в две:
CREATE TABLE IF NOT EXISTS `comment_types` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
и
CREATE TABLE IF NOT EXISTS `comments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`createdBy` int(11) DEFAULT NULL,
`createdAt` int(11) DEFAULT NULL,
`type` int(11) DEFAULT NULL,
`content` text,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Таблица comment_types
представляет собой словарь, он содержит пары ключ-значение прокомментированного элемента «тип» и его имя, например :
1:Articles
2:Photos
3:Videos
В таблице comments
хранятся обычные данные с дополнительным type
полем.
Преимущества:
- Обслуживание (добавление / удаление полей),
- Добавление новых типов комментариев «на лету».
Недостатки:
- Сложнее переносить / экспортировать,
- Возможное снижение производительности при запросе большого набора данных.
Обсуждение:
- Какой вариант хранения будет лучше с точки зрения производительности запросов (предположим, что набор данных достаточно велик для этого),
- Опять же, производительность — приведет ли добавление ИНДЕКСА к
type
удалению или значительному уменьшению этого снижения перформанса? - Какой вариант хранения будет лучше с точки зрения управления и возможной миграции в будущем (распределенный, конечно, будет лучше, но давайте посмотрим, не слишком ли далеко до централизованного)
Комментарии:
1. Ну, то, что вы предлагаете, — это упрощенная форма модели Smithamp;Smith. В этом нет ничего плохого, отличная производительность в современных реализациях SQL.
2. @wildplasser — Что такое модель Smithamp;Smith? Я впервые слышу об этом. Можете ли вы дать на него ссылку?
3. Никогда не слышал об
Smithamp;Smith
этом, не могли бы вы поделиться некоторыми ссылками / подробнее остановиться на этой теме?4. не уверен, есть ли «ответ», но мое мнение — выбрать второй вариант. — да, индексы помогут.
5. google.nl /… (Оповещение в формате PDF)
Ответ №1:
Я не уверен, что какой-либо из недостатков, перечисленных вами для варианта 2, является серьезным, экспорт данных легко выполняется с помощью простого предложения WHERE, и я бы не стал беспокоиться о производительности. Вариант 2 должным образом нормализован, и в современной реляционной базе данных производительность должна быть превосходной (и при необходимости может быть дополнительно изменена с помощью соответствующих индексов и т.д.).
Я бы рассмотрел первый вариант только в том случае, если бы мог доказать, что это было необходимо для повышения производительности, масштабируемости или по другим причинам, но должен сказать, что это кажется маловероятным.
Комментарии:
1. Вы рассмотрели большинство вопросов — спасибо. Что касается недостатков — мне пришлось что-то добавить туда, поэтому я подумал обо всем, даже маловероятном, чтобы заполнить эту часть, чтобы кто-то мог доказать, что я неправ. 🙂