在此表MySQL中设置唯一的索引类型

时间:2015-02-10 14:45:13

标签: mysql

我在此表MySQL中设置唯一的索引类型时遇到问题。

在表格doTable中,我在MyUniqueKey上设置了一个唯一的索引类型,其字段为EventDateTES

我希望当EventDateTES已经执行时,插入查询不会被执行。

DROP TABLE IF EXISTS `doTable`;
CREATE TABLE `doTable` (
  `EventDate` date DEFAULT NULL,
  `TES` varchar(4) DEFAULT NULL,
  `Dicl` int(11) DEFAULT NULL,
  `AVHS` int(11) DEFAULT NULL,
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `MyUniqueKey` (`EventDate`,`TES`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

我需要在doTable的旧行doTable_old中插入并尝试此代码:

INSERT IGNORE INTO `doTable` (
    `EventDate`,
    `TES`,
    `Dicl`,
    `AVHS`
) SELECT
    `EventDate`,
    `TES`,
    SUM(`Dicl`),
    SUM(`AVHS`)
FROM                
`doTable_old`
WHERE
`EventDate` = '2015-02-05'
`TES` = 'M201';

EventDateTES已经存在时,插入查询不会在doTable中执行。

现在我需要使用新算法更新Dicl上的字段doTable的值,我尝试过这样做:

UPDATE IGNORE `doTable` A
JOIN (
    SELECT
        SUM(tmp0.`Dicl`) AS `Dicl`
    FROM
        `doTable_cons` tmp
    JOIN `doTable_old` tmp0 ON tmp0.Codes = tmp.Codes
    WHERE
        `TES` = 'M201'
    AND `EventDate` = '2015-02-05'
    GROUP BY
        `EventDate`
    ORDER BY
        `EventDate` ASC
) AS x
SET A.`Dicl` = A.`Dicl` + x.`Dicl`
WHERE
    A.`TES` = x.`TES`;

相反,在这种情况下,即使DicldoTable已经在EventDate上,TES上的字段doTable的值也会始终更新。

我的意思是,如果我在第一次更新+2时使用旧的第10行,则新值为12,如果我再次尝试更新值14然后是16然后18 ......应该保持在12。 ..但关键是不起作用......

我错过了什么?

此代码有什么问题?

提前谢谢。

1 个答案:

答案 0 :(得分:0)

当您更改唯一键中使用的字段时,重复键才会发挥作用,导致发生重复违规,或者您插入的新记录会导致违规。

使用第二个查询时,您不会更改唯一键中使用的EITHER字段。因此,更新将继续,因为没有发生违规。

e.g。

表X(唯一键(x,y))

x    y   z
1    1   0
1    2   0


INSERT (x,y) VALUES (1,1) // fails - would create a dupe violation
INSERT (x,Y) VALUES (1,3) // succeeds - no dupe
UPDATE ... SET y=2 WHERE x=1 AND y=1 // fails - would create a dupe
UPDATE ... SET z=z+1 where x=1 AND y=1 // no problem, no dupe

换句话说,根据您的逻辑,更新数据库中的任何记录都是不可能的,因为表上的任何更改都会导致欺骗密钥违规。这显然是完全错误的。