я действительно должен использовать таблицу отношений, помечая сообщения в блоге? - PullRequest
1 голос
/ 26 января 2009

, пытаясь выяснить, как пометить сообщение в блоге одним оператором sql здесь , мне пришла в голову следующая мысль: использование таблицы отношений tag2post, которая ссылается на теги по идентификатору следующим образом, просто не необходимо:

tags
+-------+-----------+
| tagid | tag       |
+-------+-----------+
|     1 | news      | 
|     2 | top-story | 
+-------+-----------+

tag2post
+----+--------+-------+
| id | postid | tagid |     
+----+--------+-------+
|  0 |    322 |     1 |
+----+--------+-------+

почему бы просто использовать следующую модель, где вы индексируете сам тег следующим образом? Предполагается, что теги никогда не переименовываются, но добавляются и удаляются, это может иметь смысл, верно? что ты думаешь?

tag2post
+----+--------+-------+
| id | postid | tag   |     
+----+--------+-------+
|  1 |    322 | sun   |
+----+--------+-------+
|  2 |    322 | moon  |
+----+--------+-------+
|  3 |   4443 | sun   |
+----+--------+-------+
|  4 |   2567 | love  |
+----+--------+-------+

PS: я сохраняю идентификатор , чтобы легко отображать последние добавленные теги n ...

Ответы [ 5 ]

7 голосов
/ 26 января 2009

Работает, но не нормализуется, потому что у вас есть избыточность в тегах. Вы также теряете возможность использовать «одинаковые» теги для обозначения вещей помимо постов. Для малого N оптимизация не имеет значения, поэтому у меня нет проблем, если вы запустите ее.

На практике ваши индексы будут больше (если вы собираетесь индексировать теги для поиска, вы теперь индексируете дубликаты и строки). В нормализованной версии индекс в таблице тегов будет меньше, дубликатов не будет, а индекс в таблице tag2post для tagid будет меньше. Кроме того, столбцы int фиксированного размера очень эффективны для индексации, и вы также можете избежать фрагментации в зависимости от выбора кластеризации.

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

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

Ненормализованный метод может подойти в зависимости от вашего приложения. Вы можете обнаружить, что это приводит к снижению производительности из-за поиска большого набора данных VARCHAR.

При поиске вещей, помеченных как "солнце *" (например, солнце, солнце, восход солнца) вам не нужно будет делать соединение. Однако вам нужно будет сделать аналогичное сравнение с НАМНОГО большим набором данных VARCHAR. Правильная индексация может решить эту проблему, но только тестирование покажет вам, какой метод быстрее с вашим набором данных.

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

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

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

Где реальное преимущество вашего предложения перед таблицей отношений, содержащей идентификаторы?

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

Сервер БД неплохо подходит для объединения таблиц, и особенно в том случае, если соединение выполняется через поле INT с индексом. Я не думаю, что вы столкнетесь с разрушительными проблемами производительности, когда присоедините другую таблицу (например: INT id, VARCHAR(50) TagName) к своему запросу.

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

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

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

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

Я тоже об этом думал. Хотите список тегов в базе данных, просто выберите отдельный тег из tag2post. Мне сказали, что, поскольку я хотел оптимизировать операторы select, было бы лучше использовать целочисленный ключ, потому что он был намного быстрее, чем использование строки.

...