Задавайте вопросы, мы ответим
Вы не зашли.
mysql 5.0.
Задача: из таблицы "типы оборудования" удалить строку только в том случае, если в таблице "оборудование" нет ни одной единицы оборудования данного типа.
В простейшем случае все делается в 2 этапа:
1) Проверяется, что количество единиц оборудования с данным типом равно нулю
2) если условие 1 выполняется - осуществляем удаление
Однако, маловероятна, но возможна ситуация, когда между действиями 1 и 2 параллельно кто-то не создаст оборудование с целевым типом. Поэтому заходелось оформить все одним запросом (транзакциям mysql пока не доверяю, это пока не обсуэждаем).
Придумал и проверил (работает) запрос:
DELETE FROM eqtype WHERE type=(SELECT IF(COUNT(type)>0,0,5) FROM equip WHERE type=5)
- удаляет тип оборудования № 5
Вопрос. Не слишком я нахитрил и не заметил простых способов решения данной проблемы?
Неактивен
Нашел нормальный вариант:
DELETE FROM eqtype WHERE type NOT IN (SELECT type FROM equip WHERE type=5) AND type=5
Неактивен
Неактивен
не доверяю, потому что эта фича новая в мускуле, а детальной инфы по ней нет. Меня интересует поведение в критических ситуациях. Пример из другой области чтоб было понятней, что меня волнует: допустим залочил я таблицу, вдруг мой скрипт "вылетает", ну мало ли что случилось, что в этом случае будет? таблица так и останется залоченной? на сколько? Меня просто интересуют такие тонкости, критических ситуаций я повидал, взять хотя бы бока с соединениями когда не работает днс, теперь на всех серверах в конфигах мускула резолв отключаю.
За запрос спасибо, так и знал что есть красивые решения
P.S. Не совсем то - мне нужно чтоб не все удалялось, а только тот type, который я указал. Но это неважно, ваш запрос направил на вариант решения
Отредактированно dead (17.08.2008 02:24:53)
Неактивен
Резолв это известная проблема, можно его отключить, а можно прописать хост в /etc/hosts
Транзакции в MySQL допустимы при использовании движка InnoDB. Блокировки в транзакциях работают в зависимости от уровня изоляции. Следует учитывать возможность провала транзакции, то есть на запрос COMMIT можно ждать ошибки (если кто-то другой изменил эти данные и уже завершил транзакцию), в случае такой ошибки, транзакция откатывается.
Если скрипт вылетает, то соединение разрывается и MySQL должен откатить транзакцию. Хуже, если скрипт виснет, продолжая работу.
http://dev.mysql.com/doc/refman/5.1/en/ … ation.html
Неактивен
В Вашем примере, запрос SELECT в транзакции не запретит никому извенять таблицу. Следующий за ним апдейт выполнится, как это было бы вне транзакции (если таблицу не блокируют другие). При выполнении COMMIT, если данные, выбранные с помощью SELECT не были изменены другими транзакциями, транзакция завершит запись, в противном случае откатится. Я привел общее описание, конкретное поведение зависит от уровня изоляции - попробуйте с разными уровнями повыполнять параллельные транзакции.
Неактивен
Я правильно понял, что сложный запрос с подзапросом НЕ обязательно выполняется как цельная операция?
Неактивен
Цельная операция - это запись одного слова в одну ячейку памяти. Все остальные операции - составные. Если это запрос с подзапросом, то происходит логически следующее
LOCK TABLES a READ, b WRITE;
// Цикл (если требуется)
SELECT FROM a ...;
DELETE FROM b ..;
// Конец цикла
UNLOCK TABLES;
Innodb лучше тем, что блокируются не таблицы целиком, а только определенные задействованные строки (row-based locking), но это только в том случае, если возможно легко определить какие именно строки задействованы. В случае подзапроса определить это во многих случаях не удастся до исполнения запроса (и заблокируется вся таблица), а в случае двух отдельных запросов, второй будет уже конкретным SELECT FROM b WHERE id=303 и блокировка будет наложена только на строку с id=303. Это причина, почему несколько запросов часто (но не всегда) быстрее использования подзапросов.
http://dev.mysql.com/doc/refman/5.0/en/ … cking.html
Неактивен
Да, есть над чем задуматься мне... Я как раз выбирал myisam из-за больших требований к производительности чем к надежности, но смотрю все зависит от характера использования. Вероятно прийдется делать сравнительные характеристики в бою.
Чтобы не создавать новую тему, задам еще один вопрос. Есть 2 базы на разных серверах. Необходимо сделать запрос с join из таблиц в разных базах. Я так понимаю штатными средствами это сделать нельзя? Т.е. только перекидывать таблицу в другую базу?
Спасибо за ответы
Неактивен
В случае, если SELECT доминирует над UPDATE/INSERT, MyISAM лидирует по производительности. Если вставки/обновления происходят часто, одновременно с выборками, то InnoDB быстрее из-за построчной блокировки (фактичести запросы не блокируют один другой).
Требования мультиверсионности делают хранилище Innodb сложнее, чем MyISAM. Кроме того, для MyISAM работает кэш индексов http://sqlinfo.ru/articles/info/3.html а для innodb и индексы и данных кэшируются в общем кэше (Параметр: innodb_buffer_pool_size)
Можно использовать FEDERATED http://dev.mysql.com/doc/refman/5.1/en/ … ngine.html
Но: про транзакции здесь можно забыть, с производительностью надо также быть аккуратным (во многих случаях FEDERATED-таблица для выполнения запроса вынуждена выбрать всю таблицу целиком с удаленного сервера).
Неактивен
Благодарю за ответы
Неактивен