MYSQL - Проверить из Выбрать "себя" можно? - PullRequest
2 голосов
/ 25 мая 2019

Я только начал с mysql, и я не знаю, является ли способ сделать эту проверку правильным или я иду в неправильном направлении.

У меня есть varchar с именем user_num в таблице.и мне нужно проверить, что когда я делаю INSERT, значение user_num_list должно быть между [1, n], равным «n», количество объектов, которые имеют ту же группу, имеет новый объект.

Яне говорящий по-английски, и я уверен, что это немного трудно понять, и для меня, чтобы выразить себя, поэтому есть некоторый код:

create table player(
group varchar(15),
user_num int(15),
CONSTRAINT ck_player_user CHECK( user_num > 0 AND user_num < SELECT count(*) FROM player WHERE player.group=group)
)ENGINE=InnoDB;

Я не знаю, могу ли я "ВЫБРАТЬ" внутриПРОВЕРЬТЕ утверждение, а также я не знаю, как выразить «player.group = group», означая, что группа (новая INSERT player_group) должна быть одинаковой и имеет player.group

Спасибо.

Ответы [ 2 ]

0 голосов
/ 26 мая 2019

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

В теории можно было бы создать «обратную проверку». Система должна будет определить, какие операции могут нарушать проверку. В вашем случае это будет удаление строки или обновление группы. «Обратный чек» может быть

NOT EXISTS (
    SELECT *
    FROM player p
    WHERE p.group = OLD.group
      AND p.user_num > (SELECT COUNT(*) from player p WHERE p.group = OLD.group)
)

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

Так что я бы сказал - Ваши варианты:

  • Реализация ваших проверок в триггерах
  • Реализуйте свои чеки в коде приложения
  • Изменить требования

Я бы предпочел последний.

0 голосов
/ 25 мая 2019

Вам не повезло.

Прежде всего, MySQL не проверяет ограничения CHECK до версии 8.0.16.Если вы используете версию MySQL, более раннюю, чем эта, MySQL запишет ограничение CHECK и автоматически проигнорирует его .

Во-вторых, чтобы применить это ограничение, вам нужно будет использоватьподзапрос в нем, а MySQL не разрешает подзапросы как часть ограничения CHECK.См. 13.1.20.7 Ограничения CHECK , где буквально написано:

  • Подзапросы запрещены.
...