如何根据特定类别限制 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 事件中的无关条目。