отдельная таблица для элементов изображения с полем изображения - PullRequest
2 голосов
/ 02 декабря 2008

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

Мой первый дизайн был таким: таблица Элементы , а также еще одна таблица "подробности" для каждого из типов элементов ( NoteItems , ArticleItems , PictureItems и т. Д.). Чтобы извлечь отдельный элемент, таблицы должны быть объединены один в один (SELECT * FROM Items INNER JOIN PictureItems ON Items.Id = PictureItems.Id WHERE Items.Id = N).

Я почти уверен, что этот «индивидуальный» дизайн сработал бы хорошо (это делалось несколько раз), однако я начинаю задумываться, не является ли дизайн излишним. Было бы намного проще иметь одну таблицу ( Items ).

Скажем, около 5% элементов изображения или типа файла.

А теперь вопрос: если я займусь (почти) дизайном одной таблицы, лучше ли было бы в любом случае иметь детальные таблицы для полей изображения (для элементов изображения и файла, конечно)?

Сценарий 1: только одна таблица: Элементы (для хранения заметок, статей, изображений, файлов ...)

Сценарий 2: две таблицы: Элементы (для хранения заметок, статей, файлов изображений), ImageItems (для хранения только поля изображения типов элементов изображения, файла); отношение один к одному

(Сценарий 3 будет незначительным вариантом сценария 2; с 3 таблицами (Items, PictureItems, FileItems))

Преимущества сценария 1:

  • более простые запросы выбора (без объединений)
  • обновления без транзакций (только одна таблица обновляется при INSERT / UPDATE)
  • производительность, масштабируемость благодаря обновлениям без транзакций?

Преимущества сценария 2:

  • Чистый дизайн
  • меньшее потребление данных (в сценарии 1 около 95% элементов типа, отличного от изображения или файла, будут иметь значение NULL в поле изображения, то есть около 16 байт тратится на указатель)

Какой сценарий вы бы выбрали: 1 (обновления без транзакций) или 2 (снижение потребления данных)? Спасибо за ваше мнение.

Ответы [ 4 ]

2 голосов
/ 02 декабря 2008

Если программисты достаточно разумны, чтобы запрашивать только требуемые столбцы из таблицы вместо «SELECT *», первый подход к проектированию выглядит хорошо.

Необходимо позаботиться об индексировании, ссылочных ограничениях и т. Д. Для второго проекта.

0 голосов
/ 06 февраля 2009

Если вы правы в том, что только около 5% вашей строки действительно содержат дополнительные изображения / двоичные данные, то я бы определенно сказал, что используйте подход с одной таблицей в сочетании с подсказкой, которую дал Мурти, - не делайте SELECT * в этой таблице, но запрашивайте только те столбцы, которые вам действительно нужны - опускайте столбцы BLOB как можно чаще.

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

ПОЦЕЛУЙ - Держите это умным и простым - когда бы ни было возможно! : -)

Марк

0 голосов
/ 04 декабря 2008

Первый подход обычно наказывается, если вы используете какой-либо ORM или автоматически генерируете свой DAL (SubSonic?). Вы будете извлекать столбец Image (и его данные) каждый раз, когда вы передаете вокруг объекта DAL (или коллекции) поэтому обычно я использую сценарий 2 (или 3)

С точки зрения SQL любой сценарий будет работать примерно одинаково в зависимости от вашего механизма хранения (ISAM, InnoDB и т. Д.), Но даже в этом случае преимущества и различия между сценариями незначительны.

0 голосов
/ 02 декабря 2008

Если базе данных не нужно знать, что находится в этих элементах (не будет индексировать или выполнять поиск по ним), тогда вариант 1 кажется наилучшим (при условии, что у вас есть только один столбец «Элемент» в качестве BLOB) - вы можно просто считывать элементы в виде двоичных данных и самостоятельно обрабатывать их соответствующим образом, избегая, таким образом, внутреннего соединения.

Я не верю, что сценарий 2 дает вам меньшее потребление данных - вы можете просто использовать поле BLOB (и в любом случае издержки дополнительной таблицы ImageItems, вероятно, сопоставимы с 16 байтами в строке)

Так что я бы лично выбрал вариант 1, но, конечно, это зависит от того, как вы обрабатываете Предметы, когда они выходят из базы данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...