[mysql]2 таблицы + таблица соответствий, вопрос по удалению внутри...
с вариантами 2 и 3 все очевидно, поэтому у тебя наверное вариант 1?
id (data - все остальные столбцы)
pictures:
id (data)
correlation:
id picture_id topic_id
2. Удаляем те фотографии, для которых нет записей в таблице соответствий
3. Удаляем данный альбом
(П. 2 и 3 можно поменять местами)
1. Удаляем все записи из таблицы соответствий с данным id альбома1. Удаляем те фотографии, для которых есть запись в таблице соответствий
2. Удаляем те фотографии, для которых нет записей в таблице соответствий
3. Удаляем данный альбом
(П. 2 и 3 можно поменять местами)
DELETE FROM t_photo, t_corr
WHERE t_photo.id = t_corr.photo_id AND t_corr.album_id = ?
2. Удаляем все записи из таблицы соответствий с данным id альбома
DELETE FROM t_corr
WHERE t_corr.album_id = ?
3. Удаляем данный альбом
DELETE FROM t_album
WHERE t_album.id = ?
пункты менять местами нельзя
1) пункт 1 моего варианта быстрее пункта 2 варианта , а остальные пункты совпадают
2) все эти действия надо делать в пределах одной транзакции, тоесть если какаято фотография не смогла удалиться то и не надо удалять вообще ничего
в варианте если второй пункт завалится, то придется откатывать первый пункт
в моем варианте откатывать ничего не придется
DELETE FROM t_photo, t_corrЗашибись.
WHERE t_photo.id = t_corr.photo_id AND t_corr.album_id = ?
Вот быа фотография 1, которая лежала в альбоме1 и альбоме2.
После этого твоего запроса (когда удаляем альбом1) у нас из альбома2 она пропадёт, а в t_corr останется ведущая в никуда запись "фото1, альбом2".
Зашибись.ну если у вас база без внешних ключей то вам можно токо посочувствовать
Вот быа фотография 1, которая лежала в альбоме1 и альбоме2.
После этого твоего запроса (когда удаляем альбом1) у нас из альбома2 она пропадёт, а в t_corr останется ведущая в никуда запись "фото1, альбом2".
а так сработает внешний ключ: в другой таблице есть ссылки на эту запись и запись удалена не будет
про первый вариант я тоже могу сказать, что если были фотографии не принадлежищие ни одному альбому, то они удалятся
ну если у вас база без внешних ключей то вам можно токо посочувствоватьНу ты даёшь.
а так сработает внешний ключ: в другой таблице есть ссылки на эту запись и запись удалена не будет
1) Надо говорить о том, что должны быть внешние ключи, не все БД их поддерживают.
2) Ты и всё остальное так же делаешь? Типа insert into table(id,value) values(1,2 а если там такая запись уже есть - пусть не вставится, мне не страшно.
Да, и ещё - пусть есть внешние ключи, а ещё есть вполне адекватные настройки драйвера БД - "если возникла ошибка - умереть и записать ошибку в лог/на экран". Что тогда, при удалении альбома всё помирать будет?
есть вполне адекватные настройки драйвера БД - "если возникла ошибка - умереть и записать ошибку в лог/на экран"впервые про такое слышу
ничего адекватного тут не вижу
1) Надо говорить о том, что должны быть внешние ключи, не все БД их поддерживаютесть БД которые не держат внешние ключи?
очень интересно
подозреваю что такие БД и sql не держат
Типа insert into table(id,value) values(1,2 а если там такая запись уже есть - пусть не вставится, мне не страшно.а ты каждый раз перед инсертом спрашиваешь есть ли там уже такая запись?
я валяюсь
а ты каждый раз перед инсертом спрашиваешь есть ли там уже такая запись?Когда мне говорят "добавить новую запись и сделать ему id такой-то", я не говорю "отправил запрос к бд, вроде добавилось", я говорю "такая запись уже есть/успешно добавил запись/не получилось добавить запись, ошибка такая-то".
Может, человек и не знает, что это такое.
подозреваю что такие БД и sql не держатВ mysql они поддерживаются только начиная с 3.23.44 и только в InnoDB.
Вне́шний ключ (англ. foreign key) — понятие теории реляционных баз данных, поле (атрибут) таблицы, предназначенное для хранения значения первичного ключа таблицы, связанной с данной. С помощью внешних ключей в реляционных БД организуются связи между таблицами.То есть, вообще-то, foreign key-и предназначены совсем не для того, чтобы удалять только то, на что там нет ссылок; этот "автоматический контроль целостности" - всего лишь фича; и фича для контроля целостности, чтобы ничего не упало, если сделать всё неправильно, а не для повседневного использования.
...
Развитые СУБД поддерживают автоматический контроль ссылочной целостности на внешних ключах.
Когда мне говорят "добавить новую запись и сделать ему id такой-то", я не говорю "отправил запрос к бд, вроде добавилось", я говорю "такая запись уже есть/успешно добавил запись/не получилось добавить запись, ошибка такая-то".ну дык я тож так не говорю
во-первых драйвер возвращает количество добавленных
во-вторых всегда вернется код ошибки по которому понятно что произошло
по остальному: не знал, что в mysql не так давно появились эти ключи
дурацкая СУБД
Потому что так поставленную автором задачу можно решить и следующим способом:
delete * from `links` where albumid=123;а mysql сам поймёт, что там можно удалять, а что - нельзя (и вполне возможно, что до того, как у тебя будет возможность эту ошибку перехватить, завоет сирена и на экране появятся большие красные буквы "попытка удалить запись, на которую кто-то ссылается!")
delete * from `photos`;
delete * from `albums`;
delete `pictures` from `pictures`,`correlation` where `pictures`.`id`=`correlation`.`picture_id` and `correlation`.`topic_id`=123 and `pictures`.`id` not in (select `pictures`.`id` from `pictures`,`correlation` where `pictures`.`id`=`correlation`.`picture_id` and `correlation`.`topic_id`!=123);
delete `correlation` from `correlation` where `correlation`.`topic_id`=123;
delete `topics` from `topics` where `topics`.`id`=123;
Тем, кто будет что-то говорить про скорость - оптимизатор сведёт различия к нулю, зато у меня гораздо более human-readable и не полагается на какие-то сайд-эффекты (типа "если попытаться удалить запись, на которую кто-то ссылается - это, конечно, неправвильно, но она не удалится, но при этом выполнение будет продолжено, и критическая ошибка не возникнет").
ЗЫ: Первый запрос - удаляем все pictures, которые есть в нужном topic, и которых больше нет ни в одном topic. Второй запрос - удаляем все correlations для нужного topic. Третий - удаляем сам topic.
во-первых драйвер возвращает количество добавленныхОн уже ничего не возвращает, он уже сказал "ошибка!", записал её в лог и сделал exit.
1. Удаляем все записи из таблицы соответствий с данным id альбома
2. Удаляем те фотографии, для которых нет записей в таблице соответствий
3. Удаляем данный альбом
(П. 2 и 3 можно поменять местами)
Туплю. Запрос для второго действия не могу придумать...
Но моё решение лучше
ЗЫ надо больше спать...
Оставить комментарий
iakobi91
Есть две таблицы (фотоальбомы и фотографии) и таблица соответствий, соотносящая ряды в разных таблицах друг другу.Каждый элемент второй таблицы (фотография) может соответствовать сразу нескольким элементам в первой (альбом).
Как сделать удаление альбома так, что если фотография относится только к нему, то она бы удалялась, иначе удалялся бы только ряд в таблице соответствий?