【问题标题】:Can I depend on check constraint to ensure non-negative balance?我可以依靠检查约束来确保非负余额吗?
【发布时间】:2018-04-30 19:16:13
【问题描述】:

我目前有一张表如下:

CREATE TABLE Account (
 ID int NOT NULL,
 Balance int,
 CHECK (Balance>=0)
);

我还有一些应用程序伪代码如下:

function updateBalance(id Int, howMuch Int) {
 check howMuch is non zero (can be negative or positive)
 read balance for id as bal
 if bal + howMuch >= 0 update else throw error
}

我觉得读取余额和检查 >= 0 是不必要且耗时的,因为我计划使用的数据库支持检查约束(很可能是 PostgreSQL 或 H2)。某些(如 MySQL)不支持检查约束,会在 create 语句中默默地忽略它们。

我应该依靠数据库来确保非负余额还是在我的应用程序中也这样做?

【问题讨论】:

    标签: sql postgresql h2 check-constraints


    【解决方案1】:

    在数据库中使用CHECK constraint。在 PostgreSQL 中绝对可靠。

    另外,您可能仍希望在写入数据库之前检查应用程序中的输入,以避免一开始就引发异常。但是您永远不需要仔细检查从数据库中检索到的数据。这就是像 Postgres 这样的 RDBMS 的用途。

    【讨论】:

    • 引发数据库异常并捕获它或读取余额并首先检查总和是否较慢(需要一个额外的数据库查询)?
    • @Jus12:对此的一般答案是不可能的,这取决于用例。如果使用它回滚大事务,则引发异常可能会很昂贵。
    • 不幸的是,MySQL 不能这样说,因为它不支持检查约束(并且在看到它们时不会抛出错误)。所以“可靠”的使用应该取决于数据库。
    • @Jus12:当然,是的。我正在为 Postgres 发言。如果你想要“可靠”,我不会考虑 MySQL。
    【解决方案2】:

    在考虑 MVC 架构时,我们一般将业务逻辑构建在 Controller 组件中。我们也可以盲目地依赖 PostgreSQL 检查约束来检查非零约束。由于您的应用程序正在处理数据库,因此最好在应用程序内而不是在数据定义层处理检查约束。

    它使我们能够更好地控制传递异常的响应以及要传达的消息。

    【讨论】:

    • 注意点。我正在寻找最有效的(可扩展的解决方案)。使用异常可能比自己缓存数据并在应用程序内部进行检查要慢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    • 2016-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多