к примеру, у одного объявления в среднем 3 тега, на 1 миллион объявлений будет 3 миллиона записей в "объявления-теги", как там будет по скорости при выборке? Сильно я выиграю, если нарушу правило и буду писать теги, перечисляя их в строку через запятую?
1. Представим, что промежуточная таблица объявление-тег - это два гуида.
Тогда одна строчка будет занимать около 32 байт. 3*32*1000000 = 96 мегабайт (метрических)
2. Естественно, выборка будет медленной, если не добавить индекс. Индекс по id объявления ещё примерно столько же займёт. Выборка уже будет быстрее. Для фильтров ещё надо будет добавить индекс в обратную сторону - от id тега.
3. Ещё и фильтроваться по тегам можно будет, что, мне кажется, является одним из важнейших качеств тегов.
4. Если 96 мегабайт тебя пугает - используй int64 или int32 - тогда будет меньше в 2 или в 4 раза соответственно
Сильно я выиграю, если нарушу правило и буду писать теги, перечисляя их в строку через запятую?
Как уже сказали в комментах - очень сильно обосрёшься.
Выборка, конечно, будет очень быстрая, но
1. Представим что тег - это 6 букв на русском языке, а храним мы строки в Utf8 кодировке.
Тогда на каждое объявление будет тратиться 6*2*3+3+4=45 байт. Соответственно на миллион объявлений уйдёт 45 метрических мегабайт.
2. Но тут не будет индексов, по тому и фильтроваться будет очень дорого
PS: все прикидки по памяти взяты с потолка. В реальной БД числа будут другие, но примерно похожие.
PPS: если не совсем понятно, что я предлагаю, то вот:
._________. .______________. .____________.
| post | | post_tag | | tag |
|=========| |==============| |============|
| id: int |<------------| post_id: int | | id: int |
| ... | | tag_id: int |---------->| name: text |
|_________| |______________| |____________|