Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   www.boolean.name > Веб-программирование > PHP / MySQL

PHP / MySQL Создание динамических Веб-ресурсов

Ответ
 
Опции темы
Старый 21.09.2011, 09:06   #1
KRIK
Бывалый
 
Регистрация: 19.09.2005
Сообщений: 649
Написано 3 полезных сообщений
(для 3 пользователей)
Вопрос Определить количество записей, вставить запись?

Всем привет. Вот тут появилась задачка. Хочу узнать совета, как ее правильно решить. Имеется задача, чтобы сделать запись на прием. Но, на каждый день возможно записаться только для 10 человек. Я вижу решение этой задачи используя два запроса + php. Но как мне кажется, данное решение не правильно при ситуации когда будет уже записанно 9 человек и в один момент захотят записаться еще 2 или более человек.
Вот моё (неустраивающее меня решение)

Запрос 1. Получаем количество человек записанных на данный день в какую-то переменную в php (для примера день номер 1)
SELECT COUNT(id_записи),id_дня_для_записи FROM таблица_записей WHERE id_дня_для_записи=1 GROUP BY id_дня_для_записи
Запрос 2. Проводим проверку на сравнение количества человек записавшихся и возможных человек. После чего, если условие позволяет, записываем человека.
INSERT INTO таблица_записей .... VALUES(id_дня_для_записи, ....)
Ну и пошло поехало как говоря.

Но используя два запроса, как мне кажется, это во первых даст шанс записаться кому либо между ними, да и одним запросом это было бы лучше. Кто-что скажет по этому поводу?
(Offline)
 
Ответить с цитированием
Старый 21.09.2011, 10:03   #2
moka
.
 
Регистрация: 04.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,861 пользователей)
Ответ: Определить количество записей, вставить запись!!!???

Хм, попробуй использовать LOCK на таблицу.

Для того чтобы проверить, сделай одного клиента, чтобы он поставил лок, запросил колличество записей, и далее пхп скрипт ждал бы 10 секунд, затем вставил бы запись, и анлочил таблицу.

Во время этих 10 секунд, таблица по идеи будет залочена, вторым клиентом попробуй сделать ту же операцию, без ожидания, и посмотри что скажет БД.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
KRIK (21.09.2011)
Старый 21.09.2011, 18:06   #3
KRIK
Бывалый
 
Регистрация: 19.09.2005
Сообщений: 649
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Определить количество записей, вставить запись!!!???

А во время лока получается доступ имеет только один пользователь.. а чего другие тогда должны ждать 10 секунд получается!?) И кстати вот я все думаю, а реально ли объеденить те 2 запроса в один.. тогда как мне кажется распределение уже упадет на сервак, а не на наши проверки и плечи... только как вот скрестить слона с жирафом в голову пока не приходит...
(Offline)
 
Ответить с цитированием
Старый 21.09.2011, 18:11   #4
moka
.
 
Регистрация: 04.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,861 пользователей)
Ответ: Определить количество записей, вставить запись!!!???

10 секунд задержка - это я предложил для проверки и теста на работоспособность. В реальном случае, никаких задержек не нужно. Транзакция займёт менее миллисекунды, никто и ничего ждать не будет.

"Скрестить" имеется ввиду запустить один скрипт INSERT. Но ведь вопрос стоит, делать его или нет, поэтому нужно какое-то условие.
Можно через жопу - создавать всё равно, но делать потом дополнительную проверку снова на Count. И таким образом узнав что нас тут не 10 а 11, отклонять. Но тут одно условие, если Count == 11 и ты есть последний, только тогда откланять. Т.к. это же самое сделает тот кто был 10ым, но он не последний, ему откланять не нужно.
Этот подход сработает, но это дополнительная транзакция, и вставка / удаление, что говнокод в бизнес логике.

ЛОК - лучший вариант.
(Offline)
 
Ответить с цитированием
Старый 21.09.2011, 18:30   #5
KRIK
Бывалый
 
Регистрация: 19.09.2005
Сообщений: 649
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Определить количество записей, вставить запись!!!???

Ладно буду крутить вертеть)) Хоть гляну для примера чего будет)) И про 10 секунд я понял что речь не про них. Просто на примере еще не глядел)) Спасибо!
(Offline)
 
Ответить с цитированием
Старый 21.09.2011, 22:31   #6
IGR
Blitz's Shame !!
 
Регистрация: 31.03.2007
Сообщений: 3,639
Написано 832 полезных сообщений
(для 2,012 пользователей)
Ответ: Определить количество записей, вставить запись!!!???

сделал бы два запрса и непарился !!
Первый проверил возможность добавления, если уже 10 то написал бы юзеру - извините запись на прием окончена !!
Если все ок - инсерт записи !!
(Offline)
 
Ответить с цитированием
Старый 22.09.2011, 00:00   #7
moka
.
 
Регистрация: 04.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,861 пользователей)
Ответ: Определить количество записей, вставить запись!!!???

Сообщение от IGR Посмотреть сообщение
сделал бы два запрса и непарился !!
Первый проверил возможность добавления, если уже 10 то написал бы юзеру - извините запись на прием окончена !!
Если все ок - инсерт записи !!
Топик не читай - сразу отвечай.

По сути два запроса, всунуться между практически нереально, т.к. промежуток времени не более 5 мс будет, но шанс есть. Поэтому человеку нужно этот шанс минимализировать совсем.
(Offline)
 
Ответить с цитированием
Старый 22.09.2011, 05:22   #8
KRIK
Бывалый
 
Регистрация: 19.09.2005
Сообщений: 649
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Определить количество записей, вставить запись!!!???

Ну будет странно, если вдруг положено 10 человек, а вдруг когда-нибудь 11 пролезет) это не есть хорошо)
(Offline)
 
Ответить с цитированием
Старый 22.09.2011, 06:41   #9
KRIK
Бывалый
 
Регистрация: 19.09.2005
Сообщений: 649
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Определить количество записей, вставить запись!!!???

Сделал для теста вот такую наброску.

$model->lock();
print_r($model->countForDay());
sleep(10);
$model->unlock(); 
Где функции вот такие:
function lock()
    {
        
$query 'LOCK TABLES #__zapis WRITE';
        
$res mysql_query($query);
        return 
$res;
    }
    
    function 
countForDay()
    {
        
$query 'SELECT count(id_zapis) FROM #__zapis WHERE id_dnya=1';
        
$count mysql_query($query);
        return 
$count;
    }
    function 
unlock()
    {
        
$query 'UNLOCK TABLES';
        
$res mysql_query($query);
        return 
$res;
    } 
Все работает. Название таблиц просто не совпадало. А так прям как надо))

Последний раз редактировалось KRIK, 23.09.2011 в 18:07.
(Offline)
 
Ответить с цитированием
Старый 22.09.2011, 09:19   #10
cyberblut
Знающий
 
Регистрация: 14.06.2009
Сообщений: 338
Написано 139 полезных сообщений
(для 257 пользователей)
Ответ: Определить количество записей, вставить запись!!!???

INSERT INTO `YOUR_TABLE` (field1field2
SELECT 'value1''value2' 
  
FROM DUAL 
  WHERE 
(SELECT COUNT(id) as cnt FROM `YOUR_TABLEWHERE date 'SELECTED_DATE') < 9
- DUAL - виртуальная таблица, используется, если не нужно делать выборку из реальной
- value1 и value2 нужно передать напрямую из скрипта
- date - поле в которое записывается дата прихода на приём, нужно проверять в формате yyyy-mm-dd (т.е. без времени, просто день)
---
Я бы делал по следующему алгоритму:
- ввёл бы дополнительное поле request_id и сделал бы уникальным индексом
- перед запросом бы генерил уникальный ключ: $key = md5(rand(0, 999) . microtime() . date('yyyymmddHHiiss') . $personName);
- писал бы ключ внутри запроса в базу
- после проверял бы селектом, есть такой ключ в базе или нет
- если есть - запись прошла успешно

Нужно конечно ещё ловить ошибку на уникальность при инсерте и перегенеривать тогда ключ. Но я крайне сомневаюсь в возможности появления такой ситуации
(Offline)
 
Ответить с цитированием
Старый 22.09.2011, 17:57   #11
KRIK
Бывалый
 
Регистрация: 19.09.2005
Сообщений: 649
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Определить количество записей, вставить запись!!!???

А разве если этот запрос выполнить к примеру через mysql_query() мы не получим результата
выполнился запрос или нет? Помоему если мне не отказывает память мы получим false или true на выходе.
(Offline)
 
Ответить с цитированием
Старый 23.09.2011, 06:34   #12
cyberblut
Знающий
 
Регистрация: 14.06.2009
Сообщений: 338
Написано 139 полезных сообщений
(для 257 пользователей)
Ответ: Определить количество записей, вставить запись!!!???

Не получим
mysql_query() возвращает ресурс результата (или true), если в запросе НЕТ ОШИБОК. Или соответственно false, если ошибки есть.
Поэтому в данном случае, если не накосячишь с самим запросом, у тебя всегда будет true, а значит нужно будет результат проверять.
(Offline)
 
Ответить с цитированием
Старый 26.09.2011, 18:49   #13
shybovycha
ПроЭктировщик
 
Аватар для shybovycha
 
Регистрация: 27.05.2007
Сообщений: 110
Написано 40 полезных сообщений
(для 33 пользователей)
Ответ: Определить количество записей, вставить запись!!!???

Учите основы SQL: используйте транзакции. Кроме транзакции, придется использовать либо сохраненную процедуру, либо триггер BEFORE INSERT. С процедурой проще:

DELIMITER //;
CREATE PROCEDURE add()
BEGIN
SELECT @x = COUNT(id) FROM table;
IF @x < 10 THEN
INSERT INTO table ([fields]) VALUES ([field values]);
END IF;
END;
DELIMITER ;//
Потом - собсно транзакция и вызов процедуры:

START TRANSACTION;
CALL add();
COMMIT;
Объяснять как работают транзакции не буду. Скажу лишь, что коль в транзакции ничего не добавилось в таблицу - ничего страшного. А вот если ошибка вылезет - данные не изменятся. В этом и профит транзакций (кроме параллельных операций).

И да, LOCKS - наверное самая забавная идея, которую довелось слышать за неделю мне =)

Для тех, кто не понял сарказма: запросы следует выполнять лишь тогда, когда?

а) нужно получить данные
б) нужно сохранить уже готовые данные

С триггером придется поиграться...
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
moka (26.09.2011)
Старый 02.10.2011, 16:17   #14
KRIK
Бывалый
 
Регистрация: 19.09.2005
Сообщений: 649
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Определить количество записей, вставить запись!!!???

Хронимые процедуры в MySQL ? А где их там смотреть то?
(Offline)
 
Ответить с цитированием
Старый 02.10.2011, 16:34   #15
shybovycha
ПроЭктировщик
 
Аватар для shybovycha
 
Регистрация: 27.05.2007
Сообщений: 110
Написано 40 полезных сообщений
(для 33 пользователей)
Ответ: Определить количество записей, вставить запись!!!???

Сообщение от KRIK Посмотреть сообщение
Хронимые процедуры в MySQL ? А где их там смотреть то?
Ни разу не понял смысла псто...
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +1, время: 02:04.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com