简体   繁体   中英

MySQL update if exists else insert

I have a table of archived values for each channel_id, but I also want to keep the current value for each channel_id available. I first tried to put it in a separate table, but using a union on the tables for each select query was impossibly slow (I made a view of the union of the two tables).

So I guess the best alternative is to keep it in the table of archived data, with an extra column to indicate if it is the current value?

My question is then, how do I add the current value to that table if a row does not exist with the same channel_id and current column equal to 1, and update it if it does exist?

I can't see a way to make a unique index that references both channel_id and current, since many channel_ids will have current = 0. So replace won't work. And update won't always work, because the row may not exist yet.

Is there a better solution? The table will have millions of entries and there will be hundreds of thousands of channel_ids.

EDIT

CREATE TABLE `data` (
`date_time` decimal(26,6) NOT NULL,
`channel_id` mediumint(8) unsigned NOT NULL,
`value` varchar(40) DEFAULT NULL,
`status` tinyint(3) unsigned DEFAULT NULL,
`connected` tinyint(1) unsigned NOT NULL,
`current` tinyint(1) unsigned DEFAULT NULL,
PRIMARY KEY (`channel_id`,`date_time`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


CREATE TABLE `current` (
`date_time` decimal(26,6) NOT NULL,
`channel_id` mediumint(8) unsigned NOT NULL,
`value` varchar(40) DEFAULT NULL,
`status` tinyint(3) unsigned DEFAULT NULL,
`connected` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`channel_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

These are the tables I am currently dealing with. I would like to either find a good way to union these for queries (in which case the current column in the data table is not needed) or just use the data table and for a given channel_id find the one row for that channel_id that has current = 1 and if it exists, update it with a new date_time, value, status, and connected. If one doesn't exist, add it with those same values.

Look at MySQL's ON DUPLICATE KEY UPDATE syntax

http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

You absolutely can create a compound UNIQUE key.

CREATE UNIQUE INDEX ON table_name ( `channel_id`, `current` );

Then, per the other answers, you can use either REPLACE or ON DUPLICATE to update. Obviously this is a terrible idea and reformation of the table should probably happen, but it will work.

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