2016-04-28 2 views
1

У меня есть исходные данные в формате JSON следующим образом:Моделирование многозначных столбцов в РСУБД

{ 
    "id": 1, 
    "tags": [{ 
     "category": "location", 
     "values": ["website", "browser"] 
    },{ 
     "category": "campaign", 
     "values": ["christmas_email"] 
    }] 
}, 
{ 
    "id": 2, 
    "tags": [{ 
     "category": "location", 
     "values": ["website", "browser", "chrome"] 
    }] 
}, 
{ 
    "id": 3, 
    "tags": [{ 
     "category": "location", 
     "values": ["website", "web_view"] 
    }] 
} 

Категория тега и его значения генерируются динамически и не известны заранее. Мне нужно загрузить эти данные в таблицу РСУБД, а затем сделать запросы к данным. Запросы могут быть следующими:

  • Извлечь все строки, в которых место имеет значение «веб-сайт» и «браузер». Результат этого запроса должен возвращать строки с идентификаторами 1 и 2.

Мне нужна помощь в моделировании этого в схему таблицы для поддержки таких запросов. Я думал о таблицах, как:

Table 1: MAIN 
Columns: ID, TAG_LIST_ID 
Row1: 1 TL1 
Row2: 2 TL2 
Row3: 3 TL3 

Table 2: TAGS 
Columns: TAG_ID, TAG_CATEGORY, TAG_VALUE 
Row1: TID1 location  website 
Row2: TID2 location  browser 
Row3: TID3 location  chrome 
Row4: TID4 location  web_view 
Row5: TID5 campaign  christmas_email 

Table 3: TAG_MAPPING 
Columns: TAG_MAPPING_ID, TAG_LIST_ID, TAG_ID 
Row1: TMID1   TL1   TID1 
Row2: TMID2   TL1   TID2 
Row3: TMID3   TL1   TID5 
Row4: TMID4   TL2   TID1 
Row5: TMID5   TL2   TID2 
Row6: TMID6   TL2   TID3 
Row7: TMID7   TL3   TID1 
Row8: TMID8   TL3   TID4 

Теперь запросить все строки, в которых место имеет значение «веб-сайт» и «браузер», я мог бы написать

SELECT * from MAIN m, TAGS t, TAG_MAPPING tm 
WHERE m.TAG_LIST_ID=tm.TAG_LIST_ID AND 
tm.TAG_ID = t.TAG_ID AND 
t.TAG_CATEGORY = "location" AND 
(t.TAG_VALUE="website" OR t.TAG_VALUE="browser") 

Однако это вернет все три ряда; изменив условие OR на AND, не будет возвращать никакие строки. Каков правильный способ разработки схемы?

Любые указатели оценили.

ответ

1

Просто замените или на IN и счетчик:

SELECT tm.TAG_LIST_ID, count(1) as cnt 
FROM MAIN m, TAGS t, TAG_MAPPING tm 
WHERE tm.TAG_LIST_ID= m.TAG_LIST_ID 
    AND tm.TAG_ID = t.TAG_ID 
    AND t.TAG_CATEGORY = "location" AND 
    AND t.TAG_VALUE IN ("website","browser") 
GROUP by tm.TAG_LIST_ID 
having count(1) > 1 -- should be greater than 1 because you are looking for 2 words. This values change according the number of words. 
Смежные вопросы