2011-04-05 60 views
0

我有一个每个channel_id存档值的表,但我也想保持每个channel_id可用的当前值。我首先尝试把它放在一个单独的表中,但在每个选择查询的表上使用联合的速度非常慢(我对两个表的联合进行了观察)。MySQL更新如果存在其他插入

所以我想最好的选择是将它保存在归档数据表中,并附加一列来指示它是否为当前值?

那么我的问题是,如果一行中不存在相同的channel_id和当前列等于1,那么如何将当前值添加到该表中,并在存在的情况下进行更新?

我看不到一种方法来创建一个引用channel_id和current的唯一索引,因为许多channel_id将有current = 0。所以替换将不起作用。并且更新不会总是有效,因为该行可能还不存在。

有没有更好的解决方案?该表将拥有数百万条目,并且会有数十万个channel_ids。

编辑

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; 

这些是我目前正在处理的表。我想要找到一种将这些查询联合起来的好方法(在这种情况下,数据表中的当前列是不需要的),或者只是使用数据表,对于给定的channel_id,查找具有当前值的channel_id的一行= 1,如果存在,则用新的日期时间,值,状态更新并连接。如果不存在,请使用相同的值添加它。

回答

1
+0

我想我换了REPLACE和UPDATE在我的问题。我编辑它来解决这个问题。我不认为我可以使用REPLACE,因为我看不到在channel_id和current上创建唯一索引的方法,除非我创建一个全新的唯一值列。 – Patrick 2011-04-05 20:11:58

3

看看MySQL的对重复密钥更新语法

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

+0

我不认为我可以使用它,因为我看不到在channel_id和current上创建唯一标识的方法。 – Patrick 2011-04-05 20:07:57

+0

并且不要忘记在UPDATE语句中使用** VALUES(col_name)**访问器来引用传递的值。我不得不在第一次需要它的时候挖掘一个例子。 – 2011-04-05 20:22:10

0

你绝对可以创建复合UNIQUE关键。

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

然后,每其他的答案,您可以使用REPLACEON DUPLICATE更新。显然这是一个可怕的想法,桌子的改造应该可能发生,但它会起作用。

+0

但是,如果有许多具有相同channel_id和current = 0的行?我怎么能改变桌子? – Patrick 2011-04-05 20:22:07

+0

您可能不得不使用'current'之类的东西,而是使用像'archived_date'这样的真实内容。这意味着你将不得不更新日期,但目前几乎没有什么用处。 – 2011-04-05 20:29:15

+0

所有值都有一个与它们相关的Unix时间,包括当前值。但有时当前值将成为存档值,我不想覆盖它。 – Patrick 2011-04-05 20:36:19