За последние 24 часа нас посетили 22175 программистов и 1077 роботов. Сейчас ищут 686 программистов ...

MySQL приемы создания правильных БД и запросов к ним

Тема в разделе "MySQL", создана пользователем Danil, 17 дек 2008.

  1. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    armadillo
    почему? табличка то со станциями всёравно остаётся.
    а вообще что Андрей сказал далеко не новость....
     
  2. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    вот я который раз в котором проекте разгребаю завалы за такими оптимизнутыми упрощенцами, которые мне говорят "у нас данные что-то не сходятся". все надо делать соображая зачем и почему.

    связь между станциями метро и людьми у тебя где?
    и как ты будешь искать людей, которые живут близко к метро такому-то?
     
  3. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    там так и остаётся 2 таблицы, просто в таблице с людьми делается доп. поле с сериализованным(имхо лучше csv) массивом станций метро для этого человека.
    если данные не сходятся, это уже ошибка разработки редактора, база тут не причём.
    вообще у меня так объеденены таблицы юзверей и групп юзверей, а именно по полю прав...
     
  4. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    объедИнены.

    дубль надцать: напиши как ты будешь искать людей по станции метро?
     
  5. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    ну будет тяжёлый запрос...
    как то таГ
    [sql]SELECT U.* FROM связка as BT
    LEFT JOIN люди as U ON(U.id_user=BT.id_user)
    WHERE BT.id_metro='{id}'[/sql]
    вот так бывает, забудешь в вёрде проверить, так ведь кто-нибудь найдёся...кто проверит ;)
     
  6. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    не понял почему LEFT JOIN и почему этот запрос тяжелый


    но только что тут обсуждалось отказаться от связки? ))))
     
  7. а откуда у тебя возьмется id_metro, если ты хранишь сериализованный массив?
     
  8. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    наверно я чего-то упустил или не понимаю...
    но в моём представлении все 3 таблицы остаются, просто в таблицу с людьми добавляется ешё одно поле с массивом, чтоб в нагруженной части увеличить производительность...

    upd/ Прочитал пост Андрея до конца, походу он не совсем про это писал...
     
  9. 440Hz

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

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    если это про меня, то я давно "новости" не говорю, а талдычу всем прописные истины и призываю думать, думать и еще раз думать, а не "батоны давить".

    Только кто мало слушает, все хотят шишек набить, ну так, это их личное право, но есть некторые ребята которые слушаю, думаю и рзмышляют. Для таких я готов сутками отвечать.
     
  10. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    440Hz чуть меньше апломба и народ будет фтыкать лучше ))
     
  11. 440Hz

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

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    i--
     
  12. Danil

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

    С нами с:
    17 дек 2008
    Сообщения:
    13
    Симпатии:
    0
    Адрес:
    бы ни был!
    Всем привет! Я вот над чем было задумался: что быстрее? постоянные (при каждом нажатии на кнопку "Поиск") запросы к базе или создавать "временный" массив в котором будет храниться первоначальная выборка из базы.

    Пока наверно ни чего не понятно, но сразу опишу ситуацию конкретнее:

    Есть таблица отелей, гостиниц и т.д. каждая привязана к определенному городу, изначально пользователь должен выбрать город и только потом сможет производить поиск по гостиницам. Поиск по гостиницам, точнее гостиниц по параметрам, производится по единственному полю данной таблицы в котором они хранятся в виде массива с разделителями ",". Так вот я думаю как лучше сделать посылать постоянные запросы к базе когда пользователь сделал выбор параметров или сделать SELECT * FROM table WHERE town = n и все что вернется сохранить в некотором массиве и мучать уже только его.

    У кого какие соображения?

    Я вот думаю что т.к. в городе гостиниц не 100000 и параметров у них около сотни такие запросы большой нагрузки не дадут, но возможно в последствии я сделаю поиск динамическим т.е. как только пользователь поставит флажок напротив нужного ему параметра, так сразу обновится и список гостиниц отвечающих данному критерию.
     
  13. Военный

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

    С нами с:
    15 янв 2007
    Сообщения:
    70
    Симпатии:
    0
    И ещё вопрос

    Задача:
    Посчитать в рулетке сколько раз и какое число выпало после текущего числа.
    Например. Выпадения: 1,6,3,6,5,1,6. Видим, что после единицы выпало 6 2 раза, после 6 один раз 1 и один раз 5 и т.д.

    Есть таблица, в которой есть поле `chislo` INT(11) - сюда падают выпавшие числа.
    Средствами php решил в пару строк
    PHP:
    1.  
    2.     $all = $db->selectCol("SELECT chislo FROM ruletka");
    3.         $tabl = array();
    4.         for ($i=1; $i<=36; $i++){
    5.         $tabl[$i] = array_fill(1,36,0);}
    6.         $prev = 0;
    7.         foreach ($all as $now) {
    8.             $tabl[$prev][$now]++;
    9.             $prev = $now;
    10.         }
    11.         unset($tabl[0]);
    12.         ksort($tabl);
    13.  
    Но, сейчас в таблице более 20 тысяч записей - скрипт начал грузить систему.
    Теперь думаю создать таблицу, в которой буду хранить все данные, и, повесив триггер на `ruletka` прибавлять единичку в нужной ячейке.
    Т.к. нужен двумерный массив (таблица) то получается следующее:

    [sql]
    CREATE TABLE`probality` (
    `num` int(11) NOT NULL AUTO_INCREMENT,
    `0` int(2) NULL DEFAULT NULL,
    `1` int(2) NULL DEFAULT NULL,
    ...
    `35` int(2) NULL DEFAULT NULL,
    `36` int(2) NULL DEFAULT NULL,
    PRIMARY KEY (`Id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=cp1250;
    [/sql]

    Соответственно в поле num - текущее выпадение, строки - 1-36
    Поля `0` - `36` - выпаления которые были до этого. Пересечение: количество раз.
    И все бы ничего - но есть одна проблема.
    Я не могу через переменную обратиться к имени поля.
    Что я делаю: беру предыдущее число (последнее)
    [sql]
    DECLARE last INT;
    SELECT chislo INTO last
    FROM ruletka
    ORDER by id DESC
    LIMIT 1;
    [/sql]

    И теперь мне надо сделать подобный запрос:
    [sql]
    UPDATE probality
    SET last = last +1
    WHERE num = new.chislo;
    [/sql]
    Так не пускает (и это само собой)
    Пробывал так:
    [sql]
    SET CONCAT('`',last,'`') = CONCAT('`',last,'`') +1
    [/sql]
    Тоже не получилось.
    Итак вопрос:
    Можно ли имя столбца взять из переменной?
    И можно ли данную задачу решить одним sql запросом ?
     
  14. Danil

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

    С нами с:
    17 дек 2008
    Сообщения:
    13
    Симпатии:
    0
    Адрес:
    бы ни был!
    Слушай, может я чего не понял, но что если в базе хранить матрицу (таблицу) 36 на 36. В полях будут предыдущие числа, а в строках текущее. А на перекрестии будет количество выпаданий. Инкремент должен работать без проблем.

    Конечно если тебе не нужна вся история выпадений чисел то должно получиться.
    Это я так наспех сам не пробовал, если тебе не лень попробовать, то отпишись интересно :)
     
  15. Roker

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

    С нами с:
    10 апр 2007
    Сообщения:
    54
    Симпатии:
    0
    Допусти создаем скрипт который будет отправлять файлы пользователей на их сервера.
    юзеру после регистрации доступны страницы ФАЙЛЫ, СЕРВЕРЫ, ЗАДАНИЯ
    Работать должно все так:
    1. Юзер создает файлы
    2. Юзер созает список серверов
    3. Используя checkbox юзер выбирает какие файлы куда нужно отправить. Создается tasklist
    4. уже после создания tasklis могут меняться параметры серверов

    Я вижу базу такой
    Как лучше сделать табличку tasklist и вообще правильно ли я делаю базу?

    Я больше всего склоняюсь к последнему варианту tasklist. Половина полей в нем будут те же что в servers (если не все из servers. что меня и пугает) Наверное, это не правильно. при изменении параметров в servers так же будет отправляться update в tasklist. Зато вывод таблиц юзеру будет простейшим select без объединения таблиц и всяких вые....в

    Подскажите плиз. Может надо использовать ключи? А то я не совсем понимаю их суть? Или вообще все надо делать по другому?

    Нагрузка может получится не маленькой 1000users*100fils*20servers
    Да и хотелось бы не удалять все сразу а вести кое какие логи путем изменения tasklist.status

    PS Конечно много деталей опустил
    PSS Только не надо кричать иди зубри доку и поиск. Давайте обсудим эту, думаю классическую, задачу на практ примерах. По возможности.
     
  16. По хорошему, надо склонятся к первому варианту тасклиста. В базе не должно быть избыточных данных, имея их достаточное количество, их всегда можно представить в нужной форме, а изза избыточности данных легко нарушить их целостность. Денормализовать базу для получения прироста производтельности из нормализованных данных можно ВСЕГДА. Обратное — не верно. Да и в твоем случае никаких сложных обьединений не будет, простейшее экви-соединение. Это и так практически просто селект.

    По поводу нагрузки: НИКОГДА не оптимизируйте ничего «заранее». Оптимизируйте то, что требует оптимизации. Потому что иначе вы потратите ценное время на бесполезную работу.
     
  17. Roker

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

    С нами с:
    10 апр 2007
    Сообщения:
    54
    Симпатии:
    0
    Допустим нужно юзеру показать какие файлы и на какие сервера он запланировал отправить.

    Если делаем tasklist по первому варианту, тогда нужно приблизительно такой запрос?

    [sql]SELECT tasklist.tid, servers.host, files.filename, files.size FROM files, servers, tasklist WHERE tasklist.uid='$uid' and tasklist.sid=servers.sid and tasklist.fid=files.fid[/sql]
    помойму это будет сложный для выполнения запрос

    Или нужно юзать ключи и связи. Если да то как?
     
  18. Ты кто, программист или гадалка?
    возьми и сделай ЗАМЕРЫ. Изучи команду EXPLAIN. И будешь знать точно, простой он или сложный.

    «ключи и связи» использовать не надо. надо использовать индексы, в частности уникальные по первичному ключу. Они подхватятся АВТОМАТИЧЕСКИ.

    Хорошо. Этот запрос можешь не мерять, я тебе и так скажу, что он не намного медленней обычного селекта. Но начись делать замеры, и разбирать запрос с помощью EXPLAIN.

    Сам по себе твой вопрос — нормальный для начинающего. И такое спросить — не грех. Грех — не думать головой.
     
  19. JeФoks

    JeФoks Активный пользователь

    С нами с:
    16 апр 2008
    Сообщения:
    30
    Симпатии:
    0
    Проблема с выбором максимального значения в столбце id.
    Столбец автоинкрементный. Сколько строк - таков и максимальный id.

    PHP:
    1. $result = mysql_query("SELECT MAX(`id`) FROM `test`");
    2. echo $result;
    но почему-то выводит не последний id (он же - наибольший). Выводит каждый раз по-разному, вот сейчас в таблице 9 строк, он выводит 6 - максимальный id, когда было 8, он тоже выводил 6. Когда было 6 строк, он выводил 7. Вот такая арифметика.

    вставлял в запрос "AS id", тоже не помогает.

    А через sql-консоль в пхпмайадмин, запрос работает отлично, выбирает наибольший id.

    В чём может быть проблема?
     
  20. nimistar

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

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    PHP:
    1. echo $result;
    - выводит указатель на ресурс

    PHP:
    1. $result = mysql_query("SELECT MAX(`id`) as max_id FROM `test`");
    2. echo mysql_fetch_object($result)->max_id;
    может так надо ?
     
  21. JeФoks

    JeФoks Активный пользователь

    С нами с:
    16 апр 2008
    Сообщения:
    30
    Симпатии:
    0
    nimistar
    хм, что-то ничего не происходит...