如何根据特定类别限制 MySQL table 中的记录数
How to limit number of records in MySQL table based on certain category
考虑下面的 'Users' table。假设我想允许每个国家/地区最多 3 个用户(在现实世界中,这个数字可能以千为单位)。任何违反此条件的新插入都应该失败。有没有办法在数据库级别实现这一点,在并行插入期间保持数据一致?
用户Table
ID
用户名
国家
1
用户 1
美国
2
用户 2
美国
3
用户 3
美国
4
用户 4
英国
5
用户 5
英国
6
用户 6
英国
7
用户 7
US ---> 这应该会失败!!
实现此目的的一种方法是在应用程序中使用 MySQL 锁定读取,例如 'for update'。但这会影响并行插入期间的应用程序性能。
如有任何帮助,我们将不胜感激
使用交易(正如您提到的)是一个不错的选择。 MySQL 没有足够精细的约束系统来做你想做的事。而且,如果确实如此,它将对性能产生与您提到的设置相同的影响。
此外,您的 table 不会很大(假设您只有几百个不同的 Country
值)。所以交易中的工作不会很昂贵。
像这样的东西会起作用。这是一个单一的声明,所以自动提交将起作用。
INSERT INTO Users (Username, Country)
SELECT :newUserName, :newCountry
WHERE (SELECT COUNT(*) FROM Users WHERE Country = :newCountry) < 3
为什么这行得通? SELECT const, const, const FROM DUAL WHERE condition
在MySQL中可以简写为SELECT const, const, const WHERE condition
。他们不相信 Oracle DUAL
的东西。如果 condition
为假,则 SELECT returns 没有行。因此,INSERT 不插入任何行。
当您查询 table 时,也可以将此限制为三个条目。如果你有 MySQL 8+ ...这个查询就可以了。
SELECT ID, UserName, Country
FROM (
SELECT ROW_NUMBER() OVER ( PARTITION BY Country ORDER BY ID) num,
ID, UserName, Country
FROM Users
) a
WHERE num <= 3
然后您可以删除通宵工作或 MySQL 事件中的无关条目。
考虑下面的 'Users' table。假设我想允许每个国家/地区最多 3 个用户(在现实世界中,这个数字可能以千为单位)。任何违反此条件的新插入都应该失败。有没有办法在数据库级别实现这一点,在并行插入期间保持数据一致?
用户Table
ID | 用户名 | 国家 |
---|---|---|
1 | 用户 1 | 美国 |
2 | 用户 2 | 美国 |
3 | 用户 3 | 美国 |
4 | 用户 4 | 英国 |
5 | 用户 5 | 英国 |
6 | 用户 6 | 英国 |
7 | 用户 7 | US ---> 这应该会失败!! |
实现此目的的一种方法是在应用程序中使用 MySQL 锁定读取,例如 'for update'。但这会影响并行插入期间的应用程序性能。
如有任何帮助,我们将不胜感激
使用交易(正如您提到的)是一个不错的选择。 MySQL 没有足够精细的约束系统来做你想做的事。而且,如果确实如此,它将对性能产生与您提到的设置相同的影响。
此外,您的 table 不会很大(假设您只有几百个不同的 Country
值)。所以交易中的工作不会很昂贵。
像这样的东西会起作用。这是一个单一的声明,所以自动提交将起作用。
INSERT INTO Users (Username, Country)
SELECT :newUserName, :newCountry
WHERE (SELECT COUNT(*) FROM Users WHERE Country = :newCountry) < 3
为什么这行得通? SELECT const, const, const FROM DUAL WHERE condition
在MySQL中可以简写为SELECT const, const, const WHERE condition
。他们不相信 Oracle DUAL
的东西。如果 condition
为假,则 SELECT returns 没有行。因此,INSERT 不插入任何行。
当您查询 table 时,也可以将此限制为三个条目。如果你有 MySQL 8+ ...这个查询就可以了。
SELECT ID, UserName, Country
FROM (
SELECT ROW_NUMBER() OVER ( PARTITION BY Country ORDER BY ID) num,
ID, UserName, Country
FROM Users
) a
WHERE num <= 3
然后您可以删除通宵工作或 MySQL 事件中的无关条目。