LINUX.ORG.RU

[SQL] Упорядоченное удаление

 


0

1

Необходимо удалить некоторые записи из таблицы. Для предотвращения дедлоков (случаются в MySQL) процесс удаления (а также чтение) должен быть упорядоченным. MySQL поддерживает конструкцию ORDER BY в DELETE. Однако Oracle этого не поддерживает. Есть ли какой-то другой способ упорядоченного удаления, который будет работать на большенстве баз данных? По крайней мере на MySQL, Oracle, SQL Server 2005, Derby.

★★★★★

способ упорядоченного удаления

Если у вас возникла проблема «упорядоченного удаления», у вас серьезные проблемы со структурой базы данных

</thread>

no-dashi ★★★★★
()
Ответ на: комментарий от no-dashi

Может быть. Не я её проектировал.

bbk123 ★★★★★
() автор топика

Оракл что, при удалении лочит все записи попадающие под условие where? Если он лочит по одной строчке при удалении, то все должно быть ок.

dizza ★★★★★
()


[code=SQL]
delete from table_to_delete
where primary_key in ( select * from some_view )
[/code]

some_view, это вью в котором ты выбираешь первычный ключ нужной тебе таблицы, упорядочивая её как требует задача.
По идее, должно получится, так как ядро СУБД получит упорядоченный набор данных, инструкция in будет последовательно брать по одной записи.

Как-то так.

dmitryalexeeff
()
Ответ на: комментарий от dmitryalexeeff

У меня удаление происходит примерно так:

delete from tab1 where col1 in (select col1 from tab3 where col2 like ? or col2 like ?)

delete from tab2 where col1 in (select col1 from tab3 where col2 like ? or col2 like ?)

delete from tab3 where col2 like ? or col2 like ?

Последовательности этих коман могут запускаться параллельно. Только в случае параллельного запуска deadlock (в MySQL) промсходит уже в первой команде. Судя по всему delete и select лочят все строки третьей таблицы во время проверки условия. Col2 неиндексирован и я не уверен, что индексирование поможе проверять like без блокировок.

bbk123 ★★★★★
() автор топика
Ответ на: комментарий от dizza

В Oracle такой проблемы нет. В MySQL по умолчанию другой isolation level, не READ COMMITED, а REPEATABLE READ. Я его поменял на READ COMMITED, но в данном случае это не помогает, хотя решило проблему deadlock-ов в других местах.

bbk123 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

удалять по одной записи за команду

Их слишком много.

bbk123 ★★★★★
() автор топика
Ответ на: комментарий от bbk123

У меня удаление происходит примерно так:

delete from tab1 where col1 in (select col1 from tab3 where col2 like ? or col2 like ?) delete from tab2 where col1 in (select col1 from tab3 where col2 like ? or col2 like ?) delete from tab3 where col2 like ? or col2 like ?

Последовательности этих коман могут запускаться параллельно.

Сынок, ты должен начинать транзакцию с блокировки главного объекта, а потом уже переходить к подчинённым. В твоём случае это означает что в Оракле сперва надо сделать так:

select 1 from tab3 where col2 like ? or col2 like ? FOR UPDATE

... а потом уже делать то, что ты написал.

В этом случае пересекающиеся по tab3 транзакции будут заблокированы пока твоя транзакция не отпустит блокировку и таким образом ты избежишь дидлоков.

Иначе, если col1 является первичным ключом tab3, ты можешь определить что col1 в таблицах tab1 и tab2 является внешним ключот ссылающимся на tab3.col1 с опцией ON DELETE CASCADE чтобы при исполнении единственной команды «delete from tab3 where col2 like ? or col2 like ?» ссылающиеся записи также удалялись.

Понимаешь, сынок?

anonymous
()
Ответ на: комментарий от dmitryalexeeff

Если несколько таблиц с иерархией, может тогда каскадирование лучше подойдёт?

Можно об этом по-подробнее? В принципе я согласен с no-dashi, структура базы данных неправильная. Если бы вместо трёх таблиц была бы лишь одна, со всеми необходимыми колонками, такого дедлока не происходило бы.

bbk123 ★★★★★
() автор топика
Ответ на: комментарий от bbk123

Анонимус написал про это:

если col1 является первичным ключом tab3, ты можешь определить что col1 в таблицах tab1 и tab2 является внешним ключот ссылающимся на tab3.col1 с опцией ON DELETE CASCADE чтобы при исполнении единственной команды «delete from tab3 where col2 like ? or col2 like ?» ссылающиеся записи также удалялись.

Пример из офф. документации MySQL:

CREATE TABLE parent (
    id INT NOT NULL,
    PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child (
    id INT, parent_id INT,
    INDEX par_ind (parent_id),
    FOREIGN KEY (parent_id) REFERENCES parent(id)  ON DELETE CASCADE
) ENGINE=INNODB;
В данном случае создается внешний ключ parent_id, и указывается что при удалении родительской записи, будут каскадно удалены все подчинённые ей записи.

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

dmitryalexeeff
()
Ответ на: комментарий от bbk123

Уйди в туман, чучело.

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

anonymous
()
Ответ на: комментарий от anonymous

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

Научись с людьми разговаривать, перед тем как советы давать.

bbk123 ★★★★★
() автор топика
Ответ на: комментарий от bbk123

Научись с людьми разговаривать, перед тем как советы давать.

Это совет? Тогда примени его к себе, сынок.

anonymous
()
Ответ на: комментарий от bbk123

Поддерживается ли ON DELETE CASCADE всеми RDBMS, которые я перечислил вначале?

Сынок, ты для своего курсовика принципиально ни мозгом ни пальцем пошевелить не хочешь? Ответ на твой вопрос гуглится максимум за 5 минут. И короме этого, ты _должен_ читать документацию к тому, с чем ты работаешь, сынок.

anonymous
()
Ответ на: комментарий от anonymous

Это совет? Тогда примени его к себе, сынок.

Да и он касается того, как ты ко мне обращаешся. Пока ты хамишь твои комментарии мне неинтересны.

bbk123 ★★★★★
() автор топика
Ответ на: комментарий от bbk123

Сынок, я тут посмотрел твои комментарии немного, и вот что я думаю: все твои попытки как-то задеть собеседника, видение хамства даже в самом ласковом к тебе обращении, советы кому-то лечиться, обвинения участников дискуссии в троллинге и прочее - происходят от неуверенности в себе, ты просто чувствуешь что пока ни морально ни профессионально не дорос до местной аудитории и подсознательно пытаешься как-то самоутвердиться. Я вот что тебе скажу - вместо троллинга на ЛОРе лучше потрать это время на изучение мануалов к перечисленным тобой базам данных и ты даже не заметишь как с годами к тебе придёт чувство самоуважения профессионала. И это несомненно скажется на твоей способности общаться с окружающими. Читай манулы - это для тебя единственный путь, сынок.

anonymous
()
Ответ на: комментарий от anonymous

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

bbk123 ★★★★★
() автор топика
Ответ на: комментарий от bbk123

Сынок, из твоего высказывания я понял что тебе не нравится когда тебя называют «сынок» и поэтому весь сыр-бор с оскорбительными выпадами в мой адрес и обвинениями в хамстве. Ну это уже точно твоя личная проблема, сынок. Если от нормального в общем-то обращения у тебя наблюдается такая вот обострённая реакция, мешающая тебе жить нормально, то с этим надо обязательно что-то делать чтобы купировать негативное влияние, которое этот комплекс оказывает на твою жизнь, сынок.

anonymous
()
Ответ на: комментарий от anonymous

Сынок, я не собираюсь продолжать с тобой разговаривать. Ты это понял, сынок?

bbk123 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.