За последние 24 часа нас посетили 17517 программистов и 1721 робот. Сейчас ищут 1894 программиста ...

ID последней вставленной записи

Тема в разделе "PHP и базы данных", создана пользователем Dedov_Evgeniy, 18 окт 2015.

  1. Dedov_Evgeniy

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

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Здравствуйте.
    Возник такой вопрос..
    Многопользовательская система. Ну к примеру доска объявлений, работает одновременно много пользователей.
    Может ли такое произойти что один пользователь получит lastInsert_id уже вставленной записи другим пользователем.
     
  2. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Dedov_Evgeniy используй транзакции
     
  3. Dedov_Evgeniy

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

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Да, про транзакции я сразу подумал, но вопрос всё же остался - может ли такое произойти.
     
  4. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    не может. это достаточно устойчивый к отказам механизм. полученный в результате выполнения вставки идентификатор хранится на уровне сеанса и не может быть выдан другому сеансу
     
  5. Dedov_Evgeniy

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

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Спасибо, с этим вроде всё ясно, вот что написано в доках по mySql:
    Вот ещё не ясность в похожей ситуации.
    Допустим есть некая система записи на приём (к врачу к примеру). Так же много пользователей.
    При создании записи происходит проверка - нет уже записи на это время, если записей на это время Ноль то происходит INSERT.
    Тот же вопрос не получиться ли дубля в БД, если если после проверки одним польз. произойдёт вставка другим пользователем. И повиснет в БД дубль на тоже время.
     
  6. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    insert ignore поможет
     
  7. p@R@dox 55RU

    p@R@dox 55RU Зэк
    [ БАН ]

    С нами с:
    21 май 2014
    Сообщения:
    1.358
    Симпатии:
    7
    Адрес:
    с планеты Ялмез
    от дубликатов лечит ключ unique :)
     
  8. Dedov_Evgeniy

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

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Хм, дело в том что всю проверку на уровне бд в нашем случае не получается сделать.
    Алгоритм такой:
    Мы сначала получаем записи по дате и длительности, далее в php небольшой цикл проверяет что бы даты и время не пересекались и не перекрывали друг друга, и только в этом случае происходит вставка, и за это время может произойти insert другим пользователем. INSERT LOW_PRIORITY - похоже тоже не вариант
     
  9. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Делай это всё в транзакции
     
  10. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Транзакция здесь не поможет, если нет уникальности по дате и периоду.
    Нужно делать или свой алгоритм блокировки (сложно, но быстро) или блокировать всю таблицу (медленно, но просто).
    Но в принципе, ТС не прав - в SQL можно написать проверку пересечения дат и периодов. Хотя проблема блокировки на время проверки (поиска НЕпересечения с имеющимися) всё равно остаётся.
    Моя рекомендация: если число записей в БД меньше 10 шт в секунду, используйте блокировку таблицы. А когда будет тормозить в этом месте - разберётесь в алгоритмах и переделаете.
     
  11. Dedov_Evgeniy

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

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Вот уже весь BETWEEN "замусолил" так и не получилось проверить пересечение дат и периода. Если не трудно приведите пример как в SQL запросе можно проверить пересечение по датам.
    Например,
    Таблица, в ней поля дата заезда date_in и дата выезда date_out
    И как без php - проверить что бы периоды:
    1. Не пересекались
    2. Между периодом вставляемой записи не было другого более маленького периода.
     
  12. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Ну обычным меньше больше проверить

    ну во у нас занято от 20 до 40
    а ты хочешь проверить например от 35 до 105, > 35 и < 105 вот и обнаружили от 20 до 40
     
  13. Dedov_Evgeniy

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

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Да пробовал я, вариантов 1000 перебрал, и с <=<>=> и between - так и не понял странное поведение mySql. Дело в том что если проверять просто по датам - то всё норм. отрабатывает, но как только добавляешь дополнительный AND WHERE - например id_пользовтеля - то результат вообще нелогичный и вообще левые записи в результате. Весь инет перекопал уже по данному вопросу.
     
  14. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Плохо пробовали. MySQL очень даже предсказуем, за исключением нескольких мелких багов, которые почему-то не исправляются.
    Задавайте конкретные вопросы и возможно Вам помогут, а на сферические вопросы про сферического коня получите сферические ответы. ;)
     
  15. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Dedov_Evgeniy структуру и запросы в SQL показывай, ещё лучше сразу сюда http://sqlfiddle.com/
     
  16. Dedov_Evgeniy

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

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Давайте, я попробую объяснить мою проблему.
    Есть таблица в которую заносятся все записи, я не буду все поля перечислять - только ключевые.

    • id - AI
      id_user
      id_box
      date_in (тип date)
      date_out (тип date)
      [/list:u]

      Допустим в таблице есть запись:
      date_in = 2105-10-15
      date_out = 2015-10-25

      При вставке новой записи мне нужно проверить что бы новый диапазон ни каким боком на наезжал на другие (уже имеющиеся), например:

      • date_in = 2015-10-11 date_out = 2015-10-17 - заперещено
        date_in = 2015-10-16 date_out = 2015-10-20 - заперещено
        date_in = 2015-10-20 date_out = 2015-10-29 - заперещено
        date_in = 2015-10-10 date_out = 2015-10-30 - заперещено
        [/list:u]

        Вот sql:
        Код (PHP):
        1. SELECT `id` FROM `table`
        2. WHERE
        3. ('Новая date_in' BETWEEN `date_in` AND `date_out`) OR 
        4. ('Новая date_out' BETWEEN `date_in` AND `date_out`)
        5.  
        Но он не захватывает - если указать:
        Если новые даты будут:
        date_in = 2105-10-11
        date_out = 2105-10-27

        Чуть позже:
        Вот так вроде всё учитывает:
        Код (PHP):
        1. SELECT `id`, `box` FROM `orders`
        2. WHERE 
        3. ('2015-10-01' BETWEEN `date_in` AND `date_out`) OR 
        4. ('2015-10-31' BETWEEN `date_in` AND `date_out`) OR
        5. (`date_in` BETWEEN '2015-10-01' AND '2015-10-31') OR
        6. (`date_out` BETWEEN '2015-10-01' AND '2015-10-31')
        7.  
        НО, если я укажу ещё:
        Код (PHP):
        1. AND `id_box` = 32
        То sql это условие почему то не берёт во внимание.
        Он выдаст все и id_box = 32 и id_box = 56 итд.
        Почему так происходит?

        PHP, JavaScript, SQL и другой код пишите внутри тегов
        Код ( (Unknown Language)):
        1. [b]php][/b]Тут код[b][/[/b][b]code][/b][/color]
     
  17. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Покажите запрос, где Вы добавили "AND `id_box`".
     
  18. Dedov_Evgeniy

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

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Код (PHP):
    1. SELECT `id`, `id_box` FROM `orders`
    2. WHERE (`id_box` =  32) AND
    3. ('2015-10-01' BETWEEN `date_in` AND `date_out`) OR
    4. ('2015-10-31' BETWEEN `date_in` AND `date_out`) OR
    5. (`date_in` BETWEEN '2015-10-01' AND '2015-10-31') OR
    6. (`date_out` BETWEEN '2015-10-01' AND '2015-10-31')
    7.  
    PHP, JavaScript, SQL и другой код пишите внутри тегов
    Код ( (Unknown Language)):
    1. [b]php][/b]Тут код[b][/[/b][b]code][/b][/color]
     
  19. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Теперь ошибку видите?
     
  20. Dedov_Evgeniy

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

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Ой блин, вот я тупень, скобки нужны похоже.
    Так похоже нужно:

    Код (PHP):
    1. SELECT `id`, `id_box` FROM `orders`
    2. WHERE `id_box` =  32 AND
    3. (
    4. ('2015-10-01' BETWEEN `date_in` AND `date_out`) OR
    5. ('2015-10-31' BETWEEN `date_in` AND `date_out`) OR
    6. (`date_in` BETWEEN '2015-10-01' AND '2015-10-31') OR
    7. (`date_out` BETWEEN '2015-10-01' AND '2015-10-31')
    8. )
    9.  
    PHP, JavaScript, SQL и другой код пишите внутри тегов
    Код ( (Unknown Language)):
    1. [b]php][/b]Тут код[b][/[/b][b]code][/b][/color]
     
  21. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Бывает. :)
     
  22. Dedov_Evgeniy

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

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Хм. наверное можно сократить запрос и до такого?

    Код (PHP):
    1. SELECT `id`, `id_box` FROM `orders`
    2. WHERE `id_box` =  34 AND
    3. (
    4. ('2015-10-01' BETWEEN `date_in` AND `date_out`) OR
    5. ('2015-10-31' BETWEEN `date_in` AND `date_out`) OR
    6. (`date_in` OR `date_out` BETWEEN '2015-10-01' AND '2015-10-31')
    7. )
    8.  
    Chushkin А подскажите вкратце, пожалуйста такой алгоритм - принцип, ну или где почитать хотя бы можно. Спасибо.

    PHP, JavaScript, SQL и другой код пишите внутри тегов
    Код ( (Unknown Language)):
    1. [b]php][/b]Тут код[b][/[/b][b]code][/b][/color]
     
  23. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Вы наступаете на те же грабли.

    Добавлено спустя 44 секунды:
    Сейчас Вам этого не нужно, не заморачивайтесь.
     
  24. Dedov_Evgeniy

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

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Между полями AND нужно :)

    Да, в том то дело, что нужно сразу изучать - что бы было время всё тщательно обдумать, ведь позже когда посыпятся ошибки - вникать в код, даже свой, и даже грамотно написанный - довольно унылое дело :), хотя и при поддержке проектов почти всегда приходится.

    Вот тут в третьем абзаце "В РСУБД механизм..."(я его десять раз прочитал) http://kharchuk.ru/home/9-Прочее/53-mysql-transactions
    Я так понял что блокировка таблиц это и транзакция (более совершенный механизм) - это типа одно и тоже. Или я не понял...

    Вообще у нас механизм транзакций реализован на уровне абстракции и использование его в нашем решении - было бы большим плюсом...
     
  25. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Похоже вы эти грабли носите с собой ;)

    Добавлено спустя 6 минут 16 секунд:
    Не правильно.
    Транзакции, они и в Африке транзакции. От движка к движку отличаются нюансами, но принцип один - атомарность операции.
    Блокировка таблиц к транзакции имеет косвенное отношение, может использоваться, может нет. Для mySQL читайте про LOCK TABLES.