我有一个包含多组连续数据集的表,如下所示:
ID set_ID some_column n
1 'set-1' 'aaaaaaaaaa' 1
2 'set-1' 'bbbbbbbbbb' 2
3 'set-1' 'cccccccccc' 3
4 'set-2' 'dddddddddd' 1
5 'set-2' 'eeeeeeeeee' 2
6 'set-3' 'ffffffffff' 2
7 'set-3' 'gggggggggg' 1
在对这些行进行多种类型修改的事务结束时,我想确保在单个集合中,“n”的所有值仍然是顺序的(否则回滚)。它们不需要按照PK的顺序排列,只需按顺序排列,如1-2-3或3-1-2,但不要像1-3-4或1-2-3-3-4。
由于单个集合中可能有数千行,我宁愿在数据库中执行此操作,以避免在进行一些小的更改后仅仅为了验证而获取数据的开销。
还存在并发问题。锁定InnoDB(可重复读取)的方式(据我所知)是如果我在“n”上有一个索引,那么InnoDB也会锁定值之间的“间隙”。如果我将set_ID和n组合到一个索引中,是否会消除出现幻像行的问题?
在我看来,这是一个常见的问题。有什么好主意吗?
谢谢!
注意:使用MySQL + InnoDB
答案 0 :(得分:1)
查找max - min + 1 > count
:
IF EXISTS (SELECT set_ID
FROM mytable
GROUP BY set_ID
HAVING MAX(n) - MIN(n) + 1 > COUNT(n)
)
ROLLBACK
如果序列必须从1开始,请改为:
IF EXISTS (SELECT set_ID
FROM mytable
GROUP BY set_ID
HAVING MIN(n) = 1 AND MAX(n) > COUNT(n)
)
ROLLBACK
您还需要避免重复的序列号。但这可以通过在set_ID
和n
上创建唯一键来完成。
答案 1 :(得分:0)
试试这个:
IF EXISTS (SELECT set_ID
FROM mytable
GROUP BY set_ID
HAVING MIN(n) = 1 AND MAX(n) <> COUNT(DISTINCT n)
)
ROLLBACK
适用于SQL Server(我没有MySql来试用):
DECLARE @YourTable table (ID int, set_ID char(5), some_column char(10),n int)
INSERT @YourTable VALUES (1, 'set-1' ,'aaaaaaaaaa' ,1)
INSERT @YourTable VALUES (2, 'set-1' ,'bbbbbbbbbb' ,2)
INSERT @YourTable VALUES (3, 'set-1' ,'cccccccccc' ,3)
INSERT @YourTable VALUES (4, 'set-2' ,'dddddddddd' ,1)
INSERT @YourTable VALUES (5, 'set-2' ,'eeeeeeeeee' ,2)
INSERT @YourTable VALUES (6, 'set-3' ,'ffffffffff' ,2)
INSERT @YourTable VALUES (7, 'set-3' ,'gggggggggg' ,1)
INSERT @YourTable VALUES (8, 'set-3' ,'ffffffffff' ,4)
INSERT @YourTable VALUES (9, 'set-3' ,'ffffffffff' ,4)
--this will list all "bad" sets
SELECT set_ID
FROM @YourTable
GROUP BY set_ID
HAVING MIN(n) = 1 AND MAX(n) <> COUNT(DISTINCT n)
输出:
set_ID
------
set-3