我搞砸了我的数据库设计一点。这是最初的模式:
CREATE TABLE IF NOT EXISTS `xeon_stats_clicks` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`typ` enum('1','2','3','4','5','6','7','8','9') COLLATE utf8_bin NOT NULL,
`user` varchar(20) COLLATE utf8_bin NOT NULL,
`data` varchar(10) COLLATE utf8_bin NOT NULL,
`value` varchar(20) COLLATE utf8_bin NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `typ` (`typ`,`user`,`data`),
KEY `data` (`data`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;
如你所见,我在下面设置了KEY:
UNIQUE KEY `typ` (`typ`,`user`,`data`),
KEY `data` (`data`)
我执行了以下代码:
"INSERT INTO `xeon_stats_clicks` (typ, user, data, value) VALUES ('1', :username, :date, 1) ON DUPLICATE KEY UPDATE value = value + 1"
但是,上面的代码现在不起作用了,因为我的表模式现在看起来像这样:
CREATE TABLE `xeon_stats_clicks` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`typ` enum('1','2','3','4','5','6','7','8','9') COLLATE utf8_bin NOT NULL,
`user` varchar(20) COLLATE utf8_bin NOT NULL,
`data` varchar(10) COLLATE utf8_bin NOT NULL,
`value` varchar(20) COLLATE utf8_bin NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `idx_value` (`value`),
KEY `idx_typ` (`typ`),
KEY `idx_data` (`data`),
KEY `idx_user` (`user`),
KEY `data` (`data`),
KEY `data_2` (`data`)
) ENGINE=MyISAM AUTO_INCREMENT=991799 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
我如何恢复所做的更改,并返回到第一个模式,而不会弄乱表中的数据?
我不知道为什么你的第一个模式+代码不工作。
它适用于value
,即integer
:
http://sqlfiddle.com/!9/c3260/1
INSERT INTO `xeon_stats_clicks` (typ, user, data, value) VALUES
('2', 'user2', 'data3', 1) ON DUPLICATE KEY UPDATE `value` = `value` + 1
但是如果你试着把这个查询应用到其他行,它就不起作用了。因为mysql不能将VARCHAR
转换为INT
。
我猜你有错误的数据在value
列。对于您测试的(typ, user, data, value)
的组合。
UPDATE下面是您正在使用的第二个模式:
http://sqlfiddle.com/!9/5ea62b/1
正如你所看到的,如果你添加 ,你的查询也能正常工作UNIQUE KEY `typ` (`typ`,`user`,`data`),
到第二个模式。
这里是ALTER TABLE
的变体,也可以工作:
http://sqlfiddle.com/!9/57b409/1
UPDATE 2另一个猜测:你现在打破了表的唯一性
如果我没记错的话,你有
UNIQUE KEY `typ` (`typ`,`user`,`data`),
在启动项目时。过了一会儿,您确实从模式中删除了UNIQUE KEY
。这个修改允许mysql在这个表中插入重复的记录。显然,您插入了几个(或很多)重复项。现在你想应用ALTER TABLE
来获得唯一键,但mysql拒绝了,因为这个。
例如:http://sqlfiddle.com/#!——取消注释ALTER
行查看错误信息
所以你需要先修复唯一性。
UPDATE 3 Delete duplicate:
http://sqlfiddle.com/!9/85f228/1
DELETE FROM xeon_stats_clicks USING xeon_stats_clicks
INNER JOIN xeon_stats_clicks dup
ON xeon_stats_clicks.id < dup.id
AND xeon_stats_clicks.typ = dup.typ
AND xeon_stats_clicks.user = dup.user
AND xeon_stats_clicks.data = dup.data;