简体   繁体   中英

How do Adminer et al know what to update?

Here is what I am trying to understand. I have the following database table

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');

Note the absence of any indexes, unique keys... . Before someone tells me "that is not a good idea" I have strung together this example for a good reason.

Now suppose I use Adminer (you could just as easily read phpMyAdmin etc) to edit Row 2

(10,13,b)

Now after the edit if the SQL that were issued were

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

MySQL would update two rows and the table would read

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

which is not the desired result and not what Adminer does. It appears to know what row to update and does just that. It is not clear to me how this is done. With many other statements - eg CREATE TABLE it is possible to deliberately use invalid assignments (.eg attempt to assign a length to a TEXT field and then study the SQL on error. However, that option does not exist on row edits since Adminer actively stops you from doing invalid edits (eg typing in a char in an integer column).

About the only way I can think of is to tag on a LIMIT 1 at the end of the statement - which would work, kind of. However, in a table with a larger number of fields it would involve putting in a very lengthy WHERE clause when only one or two fields in that row have changed in order to help MySQL identify the right row to alter.

Perhaps there are other techniques to accomplish this that are not quite so crude that I am not aware of? I'd be most grateful to anyone who might be able to help.

To finish this post - please don't tell me that rows should be unique and I should be using indices. I am well aware of that. This is simply the worst case scenario that I am trying to resolve.


I should mention that although this question talks of MySQL I am in fact using MariaDB 10.

You've asked to update a row, but there is no unique identifier that can be used, therefore, the software took as much constant data as it had to update the database. That data, the values of Field0 and Field1 was not unique, and so it changed all the rows it matched. If ( Field0 , Field1 ) was a unique key, or there was a (unique) primary key, it could have changed only a single row.

If ( Field0 , Field1 ) was NOT unique, and you had added a LIMIT 1 , it still may have had the option to change the one other row that matched.

Without a unique way to refer to every separate row (and that would be with a primary key without NULLs), you are effectively breaking Codd's 12 rules , particularly rule #2. Since a 'perfect' relational database is mostly theoretical and impractical for everyday use, DBs can happily exist without strict compliance, but without a unique key in this instance you are just making life hard for yourself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM