Оптимизированная структура таблицы для таблицы тегов - PullRequest
4 голосов
/ 12 января 2009

Рассмотрим эти 3 структуры таблицы. Который будет выполнять эти запросы лучше всего.

Структура 1 - TagID как int с таблицей соединений

Article
-------
ArticleID int

Article_Tag
------------
ArticleTagID int
ArticleID int
TagID int

Tag
---
TagID int
TagText varchar(50)

Структура 2 - теги только в таблице соединений в виде строки

Article
-------
articleID int

Article_Tag
-----------
articleTagID int
articleID int
tag varchar(50)

Структура 3 - Пометить как текст как PK

Article
-------
ArticleID int

Article_Tag
------------
ArticleTagID int
ArticleID int
Tag varchar(50)

Tag
---
Tag varchar(50)

Примеры запросов:

Select articleID from Article a inner join Article_tag at on a.articleID = at.articleID and tag = 'apple'
Select tag from Tags -- or, for structure 2
Select distinct tag from article_tag

Ответы [ 7 ]

5 голосов
/ 12 января 2009

Зависит от того, хотите ли вы когда-нибудь изменить глобальный текст тега. Вы, конечно, могли бы выполнить широкий UPDATE для Article_Tag, но если вам нужно это сделать, то возможность просто обновить значение в Tag будет проще. Некоторые серверы предлагают автоматические обновления (например, ON UPDATE CASCADE в SQL Server), но они не обязательно дешевы (все равно приходится UPDATE много строк и любые заданные индексы).

Но если вам это не нужно, то с литералом в Article_Tag он должен быть немного быстрее, поскольку он может удалить соединение - много раз. Очевидно, индексировать это и т. Д.

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

Что касается первичного ключа; если у вас нет других данных для хранения, зачем вам такая таблица? Вы можете использовать DISTINCT на Article_Tag так же легко, особенно если индексировать Tag (так что это должно быть довольно дешево). ( edit Билл Карвин правильно указывает на то, что можно хранить допустимых тегов, а не только текущих тегов).

4 голосов
/ 12 января 2009

Использование TagText в качестве первичного ключа имеет то преимущество, что вы можете получить теги статей с меньшим числом объединений:

SELECT * FROM Article_Tag WHERE Article_ID = ?

Недостатком будет то, что строки тегов занимают больше места, чем целые числа, поэтому память для Article_Tag и ее индексов будет больше. Это занимает больше места на диске, а также требует больше памяти для кэширования индекса.

2 голосов
/ 28 января 2009

Я бы пошел с 1 каждый раз. Он полностью нормализован, и поскольку вы используете синтетический PK, вы можете изменить имя тега с помощью обновления одной строки.

Единственным преимуществом в противном случае является уменьшение количества объединений. Это оптимизация, которую мы все знаем, что вы должны делать только после измерения. Если бы вы были уверены, что структура 1 не была достаточно быстрой, вы бы не спрашивали, верно?

Теперь между 2 и 3 нет большой разницы, но, как отмечает Билл Карвин, 3 имеет преимущества с точки зрения каскадных обновлений. Более того, дополнительная таблица ничего не теряет.

Итак, я бы сказал, что переходите к 1. Если есть проблема измеримой (т.е. настраиваемой) производительности, тогда 3 будет вполне приемлемым. В любом случае, потом будет нелегко мигрировать.

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

Таблица с PK AUTO_INCREMENT не будет масштабироваться. Забудьте о TagID как INTEGER и замените его тип на BINARY (16), достаточный для контрольной суммы MD5 TagText.

И при правильном уровне кэша вашему SQL-запросу не потребуется столько столбца TagText, сколько нужно.

0 голосов
/ 29 января 2009

Я бы пошел на Структуру 2, возможно, просто назвал бы таблицу Article_Tag - Теги .

0 голосов
/ 28 января 2009

Вы должны отображать код TagText в TagId в коде (и в любом случае отображать в кэш в памяти) и передавать предварительно сопоставленный TagId в ваш запрос.

Также нет причин, по которым вам нужен синтетический ключ для таблицы Article_Tag. Вы должны использовать составной первичный ключ (ArticleId, TagId).

Итак, я говорю # 1 с незначительной настройкой, упомянутой выше.

0 голосов
/ 28 января 2009

С возвращением, скромность. Или Localghost, или Шон, или как ты сейчас себя называешь. Просто помните, что значка «Хакеры» больше нет, поэтому выиграть здесь нечего:)

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