Очень хотелось бы услышать ваше мнение и советы: Нужно сохранить в базе данных следующее. Есть несколько тем, например: 1.Судостроение 2.Медицина 3.Экономика 4.Техника ... 99. Строительство Человек заполняет форму, и отмечает галочками те варианты которые он умеет, соответственно он может выбрать и все темы, и только 1 тему, или вообще ничего. Вопрос заключаеться в следующем - как лучьше всего хранить ответ пользователя? В голову лезет мысль о создании столбца в котом будут перечислены номера тем через запятую. (но потом как мне кажеться будет проблемно извлекать данные из этого столбца при помощи одного SQL - имею в виду запросы типа: "выбрать людей, которые знают тему строительство") Короче говоря я в смятении. Кто что может посоветовать?
Если количество тем в таблице может меняться то проще всего сделать сводную таблицу. Так например есть таблица "Themes" и таблица "Users". У каждой темы и пользователя есть ID. Собственно делаем таблицу вида: theme_id, user_id И в этой таблице указываем какую тему какой пользователь знает. В плане запросов на выборку - они получаются простые. + Можно реализовать связи между полями таблиц и получить например каскадное удаление всех записей. Минусы тоже есть, поскольку при большом количестве записей слишком нормализованная структура БД может подтормаживать.
evgenyt, отлично, спасибо большое - этот вариант супер просто как подходит. еще раз огромное спасибо!
Danilevsky на будущее если тем ~30 , то можно все запихать в INT и хранить как битовую маску, но это для ограниченного применения. зато выборки быстрые.
с битовыми масками кто-то игрался? Как с ними работают индексы? Есть поле для связи либо с таблицей А, либо с Б, но никогда одновременно. Склоняюсь к разделению на два поля, один из который всегда будет 0 - думаю так будет быстрее чем проверять флаг А или Б.
Чем больше читаю этот форум, тем больше боюсь писать что-то сложнее "мама, папа, каша". Для меня вот такой вариант вполне удобен. PHP: function getnumlist4bit($n) { //функция вычисляет все возможные значения поля flags при заданном флаге (бите) $maxbit=5; $out=array(); $x=1<<($n-1); / / степени двойки for ($i=0;$i<$maxbit*2;$i++ ) { if ($i & $x) $out[]=$i; } return $out; } PHP: SELECT adr_id FROM adr, str WHERE adr_flags IN (".implode(',',getnum4bit(1)).") AND adr_str=str_id AND str_name like '%ая%' union SELECT adr_id FROM adr,str_input WHERE adr_flags NOT IN (".implode(',',getnum4bit(1)).") AND AND adr_str=str_id AND str_name like '%ая%' но насколько это будет понятно тому, кто будет разбирать когда я уйду? (хотя потребоваться должно не скоро) не лучше ли сделать "проще" where adr_flag1=1... where adr_flag1=0... where adr_flag2=1... ?