I can't reveal the actual kind of data I'm storing but imagine I have a database of weatherstations and their updates.
The updates-table would be something like the following:
CREATE TABLE `updates` (
`weatherStationId` INT NOT NULL,
`time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`temperature` DECIMAL(10,7) NULL,
`humidity` DECIMAL(10,7) NULL,
CONSTRAINT `FK__weatherstations` FOREIGN KEY (`weatherStationId`) REFERENCES `weatherstations` (`id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
And look something like this for instance:
╔══════════════════╦═════════════════════╦═════════════╦══════════╗
║ weatherStationId ║ time ║ temperature ║ humidity ║
╠══════════════════╬═════════════════════╬═════════════╬══════════╣
║ 69 ║ 2015-03-06 00:04:56 ║ 4 ║ 29 ║
║ 1337 ║ 2015-03-08 12:22:33 ║ 29 ║ 38 ║
╚══════════════════╩═════════════════════╩═════════════╩══════════╝
When there's an update, I'd like to compare the new values(temperature & humidity) of those of the previous ones, e.g. the record with the latest time-value among those of the same weatherstationId as the one we've got an update for. If those values are not the same, or there are no stored updates for that weatherstation then I simply want to insert the record with the new values. Otherwise I'd like to change the time of the latest record to now().
So with an update for weatherId 69 with a temperature of 4 and humidity of 30 at 2015-03-07 12:00:00 the table above would become:
╔══════════════════╦═════════════════════╦═════════════╦══════════╗
║ weatherStationId ║ time ║ temperature ║ humidity ║
╠══════════════════╬═════════════════════╬═════════════╬══════════╣
║ 69 ║ 2015-03-06 00:04:56 ║ 4 ║ 29 ║
║ 1337 ║ 2015-03-08 12:22:33 ║ 29 ║ 38 ║
║ 69 ║ 2015-03-09 12:00:00 ║ 4 ║ 30 ║
╚══════════════════╩═════════════════════╩═════════════╩══════════╝
(Values differ from rest so insert new record)
With the same update except with a humidity of 29 instead, the table should now look like this:
╔══════════════════╦═════════════════════╦═════════════╦══════════╗
║ weatherStationId ║ time ║ temperature ║ humidity ║
╠══════════════════╬═════════════════════╬═════════════╬══════════╣
║ 69 ║ 2015-03-09 12:00:00 ║ 4 ║ 29 ║
║ 1337 ║ 2015-03-08 12:22:33 ║ 29 ║ 38 ║
╚══════════════════╩═════════════════════╩═════════════╩══════════╝
(New values are same as previous, so only update the time in the old record to that of the new record. or if you will, insert new record and delete the old)
Currently I do this in PHP which is a no-brainer. As of now I have no real issues with this approach. I just thought there might be a way of doing it all with one sql-statement which I suspect would mean less and more clean code, as well as better performance as I think that could become a small issue as the database grows.
I found the following question&answer that deals with a similar issue MySQL: Do not insert a new row if defined rows are same
The problem is that in my case I'm inserting updates for tens of thousands of "weatherstations" at once. And I was unable to get that solution to work with a multi-insert. Is there a way?