Как сохранить, чтобы удалить строки с запросом в предложении where - PullRequest
0 голосов
/ 07 апреля 2020

У меня есть объект Head (таблица Head ), который может иметь 0 или n позиций (таблица Position ).

таблица HEAD

HEAD_ID  NAME
1        A
2        B

таблица POSITION

HEAD_ID  POS_ID  VALUE
1        1       X
1        2       Y
2        1       Z
3        1       DELETE ME

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

Мой сценарий удаления

DELETE  POSITION
WHERE HEAD_ID NOT IN (SELECT HEAD_ID FROM HEAD)

Вопрос: Как работает команда, если во время выполнения сценария удаления в таблицы вставляются строки? В моем сценарии обе таблицы имеют несколько 10.000 строк, и поиск может занять некоторое время.

Если я правильно понимаю, список HEAD_ID из HEADS создается один раз в начале команды. Поэтому вновь добавленные строки не будут в списке и будут удалены. Это верно?

Команда удалит позицию с HEAD_ID = 3 и POSITION_ID = 1 в моем примере, так как голова отсутствует.

Но как это работает, если после SELECT и перед DELETE в обе таблицы будут добавлены новые записи:

Таблица HEAD

HEAD_ID  NAME
1        A
2        B
4        NEW HEAD

Таблица POSITION

HEAD_ID  POS_ID  VALUE
1        1       X
1        2       Y
2        1       Z
3        1       DELETE ME
4        1       WILL I BE DELETED?

Будет ли удалена новая позиция с HEAD_ID = 4 и POSITION_ID = 1, так как головка не была в SELECT?

Есть ли способ выполнить задачу более безопасным способом?

1 Ответ

0 голосов
/ 07 апреля 2020

Вы можете использовать MySQL функцию блокировки таблицы для операции удаления, тогда никакие новые данные не будут вставлены, пока ваша операция удаления не завершится sh. Сначала заблокируйте таблицы

LOCK TABLES table_name WRITE

Затем выполните операцию удаления и после снятия блокировки таблицы

UNLOCK TABLES;

MySQL позволяет сеансу клиента явно получить блокировку таблицы для предотвращения других сеансов от доступа к той же таблице в течение указанного c периода.

Сеанс клиента может получить или снять блокировки таблицы только для себя. И сеанс клиента не может получить или снять блокировки таблицы для других сеансов клиента.

Ссылка: https://www.mysqltutorial.org/mysql-table-locking/

...