За последние 24 часа нас посетили 20118 программистов и 1695 роботов. Сейчас ищут 1832 программиста ...

Несколько вариантов

Тема в разделе "PHP и базы данных", создана пользователем Danilevsky, 22 мар 2006.

  1. Danilevsky

    Danilevsky Активный пользователь

    С нами с:
    12 фев 2006
    Сообщения:
    286
    Симпатии:
    0
    Адрес:
    Киев
    Очень хотелось бы услышать ваше мнение и советы:
    Нужно сохранить в базе данных следующее. Есть несколько тем, например:

    1.Судостроение
    2.Медицина
    3.Экономика
    4.Техника
    ...
    99. Строительство


    Человек заполняет форму, и отмечает галочками те варианты которые он умеет, соответственно он может выбрать и все темы, и только 1 тему, или вообще ничего. Вопрос заключаеться в следующем - как лучьше всего хранить ответ пользователя?

    В голову лезет мысль о создании столбца в котом будут перечислены номера тем через запятую. (но потом как мне кажеться будет проблемно извлекать данные из этого столбца при помощи одного SQL - имею в виду запросы типа: "выбрать людей, которые знают тему строительство")

    Короче говоря я в смятении. Кто что может посоветовать?
     
  2. evgenyt

    evgenyt Активный пользователь

    С нами с:
    9 мар 2006
    Сообщения:
    53
    Симпатии:
    0
    Адрес:
    Russia, Murmansk
    Если количество тем в таблице может меняться то проще всего сделать сводную таблицу. Так например есть таблица "Themes" и таблица "Users". У каждой темы и пользователя есть ID.

    Собственно делаем таблицу вида: theme_id, user_id
    И в этой таблице указываем какую тему какой пользователь знает.

    В плане запросов на выборку - они получаются простые. + Можно реализовать связи между полями таблиц и получить например каскадное удаление всех записей.

    Минусы тоже есть, поскольку при большом количестве записей слишком нормализованная структура БД может подтормаживать.
     
  3. Danilevsky

    Danilevsky Активный пользователь

    С нами с:
    12 фев 2006
    Сообщения:
    286
    Симпатии:
    0
    Адрес:
    Киев
    evgenyt, отлично, спасибо большое - этот вариант супер просто как подходит. еще раз огромное спасибо!
     
  4. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    Danilevsky
    на будущее если тем ~30 , то можно все запихать в INT и хранить как битовую маску, но это для ограниченного применения. зато выборки быстрые.
     
  5. Belegnar

    Belegnar Активный пользователь

    С нами с:
    11 фев 2006
    Сообщения:
    299
    Симпатии:
    0
    Чего ж там ограниченного? Насколько я помню, мискль поддерживает в селектах логические операции.
     
  6. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    с битовыми масками кто-то игрался? Как с ними работают индексы?
    Есть поле для связи либо с таблицей А, либо с Б, но никогда одновременно.
    Склоняюсь к разделению на два поля, один из который всегда будет 0 - думаю так будет быстрее чем проверять флаг А или Б.
     
  7. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    Ответ: плохо.
    where flags & 2 - possible_keys - NULL, where flags>1 - possible_keys - flags
     
  8. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    Чем больше читаю этот форум, тем больше боюсь писать что-то сложнее "мама, папа, каша".
    Для меня вот такой вариант вполне удобен.
    PHP:
    1. function getnumlist4bit($n) {
    2. //функция вычисляет все возможные значения поля flags при заданном флаге (бите)
    3. $maxbit=5;
    4. $out=array();
    5. $x=1<<($n-1); / / степени двойки
    6. for ($i=0;$i<$maxbit*2;$i++ ) {
    7.     if ($i & $x) $out[]=$i;
    8.    
    9. }
    10. return $out;
    11. }
    PHP:
    1. SELECT adr_id FROM adr, str WHERE adr_flags IN (".implode(',',getnum4bit(1)).") AND adr_str=str_id AND str_name like '%ая%'
    2. union
    3. 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...

    ?