是否更好的做法是计算所有行,或将变量存储在表示行数的相关表中?

时间:2017-11-29 15:02:55

标签: mysql sql

假设业务规则希望防止滥用在表中存储太多行的用户,无论这些行对应于...

要强制执行此规则,最好在CRUD操作时计算所有行并验证用户是否未超过最大行数?或者,在表中存储整数并在创建或删除行时更新该数字会更好吗?

3 个答案:

答案 0 :(得分:0)

在字段本身中使用count更不可取,最好有计数查询并使用它,如果你有一个计数字段,并且在字段上做任何更改将无法得到你期望的精确结果。使用count()查询而不是存储在字段中。

答案 1 :(得分:0)

没有正确答案。我建议你从简单开始,但要准备好扩展。也就是说,从对实时数据的计数查询开始来强制执行约束,但是将其抽象出来以便封装计数逻辑。

在扩展时,您可能会遇到任何需要将其归一化为存储值的问题:

  1. 存储上的表,其中有足够的行来强调底层存储IOPS
  2. 需要进行非平凡索引扫描的计数查询
  3. 计数查询,其运行次数与写入锁定
  4. 相同

    如果切换到存储值,则必须平衡精确的最新计数需求和计算该值的成本。这是你正在努力实现的真正平衡。在开发的早期,计算计数的成本是微不足道的:当你扩展时,情况并非如此。用封装计划它。

答案 2 :(得分:0)

您可以在(business_column,version_num)上创建唯一索引,并在版本列上添加检查约束,例如最多x。然后DB将执行您的规则。

示例:

CREATE TABLE tab(
    ID INT PRIMARY KEY AUTO_INCREMENT,
    b_col INT,
    version_num INT,
    CHECK (version_num BETWEEN 1 AND 3),
    UNIQUE(b_col, version_num)
);

INSERT INTO tab(b_col, version_num)
VALUES (1, 1),(1,2),(1,3);

INSERT INTO tab(b_col, version_num)
VALUES (1,4);
-- CONSTRAINT `CONSTRAINT_1` failed for `fiddle_CIHMJQBAGQNCFTVVIHZQ`.`tab`

INSERT INTO tab(b_col, version_num)
VALUES (2,1),(2,2);

SELECT *
FROM tab;

<强> DBFiddle Demo

注意:要强制执行CHECK约束,您需要使用MySQL 8.0 / MariaDB