2008-12-02 6 views
2

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

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

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

Предположим, что существует около 5% элементов изображения или типа файла.

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

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

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

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

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

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

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

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

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

+0

Мы здесь работаем над случаем, когда содержимое файла хранится в полях базы данных, не так ли? Вы когда-нибудь сохраняли имена файлов (и, в конечном итоге, pathes) в своей базе данных? – 2008-12-02 09:49:49

+0

Обычно я не ставил двоичные данные в базу данных. Пути отлично работают. – 2008-12-03 17:33:36

ответ

0

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

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

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

2

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

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

0

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

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

0

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

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

KISS - Держите это умным и простым - по возможности! :-)

Marc