2015-03-05 2 views
8

У меня есть стол "posts". Каждая запись может иметь один или несколько тегов. Если я храню теги в одном столбце, в качестве строки с разделителями-запятыми, я могу легко найти сообщения с тегом «Abc» и тегом «Def» или даже выполнить частичное сопоставление.Соответствие из нескольких отношений

Я использую sqlite и таблицу «FTS» с помощью этого метода, и он отлично работает, но кто-то сказал мне, что это плохая практика, и я должен хранить теги в другой таблице и использовать JOINs. Если я храню теги в другой таблице и создаю связь между этими двумя таблицами, как мне найти сообщения с тегами «Abc» и тегом «Def» в одном запросе? Является ли это возможным?

ответ

0

Если вы хотите нормализовать свою базу данных, я бы определенно разделил эту информацию на несколько таблиц. Я написал схему и некоторые примеры запросов, показывающих, как вы можете вытащить данные. Вы можете это увидеть здесь: http://sqlfiddle.com/#!9/48ebb/15

В основном вы есть 3 таблицы:

  • POST Таблица: содержит запись информации.
  • POSTTAGS Таблица: Является ли присоединение таблицы, содержащей идентификатор из таблицы POST и таблиц TAG
  • TAG таблица: содержит информацию о тегах

Таким образом, вы никогда не хранить ту же самую информацию тегов дважды.

Наконец вот пример запроса от sqlfiddle размещен выше:

-- find all posts with the tags associated with them 
SELECT DISTINCT POST.*, GROUP_CONCAT(tagName SEPARATOR ', ') AS associatedTags 
FROM POST 
    INNER JOIN POSTTAGS ON POST.postId = POSTTAGS.postId 
    INNER JOIN TAG ON TAG.tagId = POSTTAGS.tagId 
1

Это действительно плохая практика дизайна.

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

Лучше дизайн будет

tags table 
---------- 
id 
name 


posts table 
----------- 
id 
title 
body 
... 


post_tags table 
--------------- 
post_id 
tag_id 

Чтобы получить все посты как теги сделать

select p.id, p.title, p.body 
from posts p 
join post_tags pt on pt.post_id = p.id 
join tags t on pt.tag_id = t.id 
where t.name in ('abc','def') 
group by p.id, p.title, p.body 
having count(distinct t.id) = 2 
Смежные вопросы