Sql 我可以依靠支票约束来确保非负余额吗?

Sql 我可以依靠支票约束来确保非负余额吗?,sql,postgresql,h2,check-constraints,Sql,Postgresql,H2,Check Constraints,我目前的表格如下: 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 u

我目前的表格如下:

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
}
我还有一些应用程序伪代码,如下所示:

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
}
我觉得读取balance和检查>=0是不必要的,也是很耗时的,因为我计划使用的数据库支持检查约束(很可能是PostgreSQL或H2)。某些约束(如MySQL)不支持检查约束,并将在create语句中自动忽略它们)

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

在数据库中使用a。它在PostgreSQL中绝对可靠


此外,在写入DB之前,您可能仍然希望检查应用程序中的输入,以避免引发异常。但您永远不需要对从数据库检索到的数据进行双重检查。这就是像Postgres这样的RDBMS的用途。

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


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

引发DB异常并捕获它或读取余额并首先检查总和(需要一个额外的DB查询)的速度较慢吗?@Jus12:这是不可能的,这取决于用例。如果一个大的事务被回滚,引发异常可能会很昂贵。不幸的是,MySQL不能这么说,因为它不支持检查约束(并且在看到它们时不会抛出错误)。所以“可靠”的使用应该取决于数据库。@Jus12:当然,是的。我代表博士后发言。如果你想要“可靠的”,我不会考虑MySQL。我正在寻找最高效(可扩展的解决方案)。使用异常可能比自己缓存数据和在应用程序内部执行检查要慢。