Как Adminer и другие знают, что обновлять?

Вот что я пытаюсь понять. У меня есть следующая таблица базы данных

DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`Field0` int(11) NOT NULL,
`Field1` int(11) NOT NULL,
`Field2` enum('a','b','c') COLLATE latin2_czech_cs NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin2 COLLATE=latin2_czech_cs;

INSERT INTO `test` (`Field0`, `Field1`, `Field2`) VALUES
(10,    11, 'a'),
(10,    13, 'b'),
(10,    13, 'a');

Обратите внимание на отсутствие каких-либо индексов, уникальных ключей … Прежде чем кто-то скажет мне, что это не очень хорошая идея, я привел в пример этот пример по уважительной причине.

Теперь предположим, что я использую Adminer (вы можете так же легко прочитать phpMyAdmin и т. Д.) Для редактирования строки 2

(10,13,b)

Теперь после редактирования, если SQL были выпущены были

UPDATE `test` SET Field2 = 'c' WHERE Field0 = '10' AND Field1 = '13';

MySQL обновит два ряда и таблица будет читать

(10,11,a)
(10,13,c)
(10,13,c)

что не является желаемым результатом и не то, что делает Администратор. Кажется, он знает, какую строку обновлять, и делает именно это. Мне не понятно, как это делается. Со многими другими утверждениями — например, CREATE TABLE можно намеренно использовать недопустимые назначения (например, попытаться назначить длину TEXT поле, а затем изучить SQL на ошибки. Однако, эта опция не существует при редактировании строк, так как Adminer активно запрещает вам делать недопустимые изменения (например, вводить символ в столбце целых чисел).

О единственном способе, которым я могу думать, является пометка на LIMIT 1 в конце заявления — что будет работать, вроде. Тем не менее, в таблице с большим числом полей это будет включать в себя очень длинное предложение WHERE, когда только одно или два поля в этой строке изменились, чтобы помочь MySQL идентифицировать право строка для изменения.

Возможно, есть другие методы для достижения этой цели, которые не настолько грубы, о которых я не знаю? Я был бы очень благодарен любому, кто мог бы помочь.

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


Я должен упомянуть, что хотя этот вопрос говорит о MySQL, на самом деле я использую MariaDB 10.

0

Решение

Вы попросили обновить строку, но нет уникального идентификатора, который можно было бы использовать, поэтому программное обеспечение получало столько же постоянных данных, сколько и для обновления базы данных. Эти данные, значения Field0 а также Field1 не был уникальным, и поэтому он изменил все подходящие строки. Если (Field0, Field1) был уникальным ключом, или существовал (уникальный) первичный ключ, он мог изменить только одну строку.

Если (Field0, Field1) не был уникальным, и вы добавили LIMIT 1, он все еще мог иметь возможность изменить один Другой строка, которая соответствует.

Без уникального способа ссылаться на каждую отдельную строку (и это было бы с первичным ключом без NULL), вы фактически нарушаете 12 правил Кодда, особенно правило № 2. Поскольку «идеальная» реляционная база данных в основном теоретическая и непрактичная для повседневного использования, БД могут счастливо существовать без строгого соответствия, но без уникального ключа в этом случае вы просто усложняете себе жизнь.

0

Другие решения

Других решений пока нет …