Sql 向上投票和向下投票数据库

Sql 向上投票和向下投票数据库,sql,database,Sql,Database,如果我有一个用于文章的数据库,并且我有一个用于投票的字段。 我正在考虑创建一个SQL查询,使用该查询,我将首先获得upvots的当前值,然后将该值增加1 但是如果5个人同时点击upvote按钮会发生什么呢 或者有没有更好的方法来做到这一点*有两种解决方案: 如果确实需要将值加载到应用程序中并在其中递增,然后再写回,请在选择值之前在表上获得适当的锁。完成值后释放锁。要么是因为取消投票,要么是因为重写了实际的追加投票 否则,并发实例B可以读取相同的值,并在第一个实例a之后将其写回。假设两者都读取3。

如果我有一个用于文章的数据库,并且我有一个用于投票的字段。 我正在考虑创建一个SQL查询,使用该查询,我将首先获得upvots的当前值,然后将该值增加1

但是如果5个人同时点击upvote按钮会发生什么呢


或者有没有更好的方法来做到这一点*

有两种解决方案:

如果确实需要将值加载到应用程序中并在其中递增,然后再写回,请在选择值之前在表上获得适当的锁。完成值后释放锁。要么是因为取消投票,要么是因为重写了实际的追加投票

否则,并发实例B可以读取相同的值,并在第一个实例a之后将其写回。假设两者都读取3。两者都将其增加到4。然后A在B之前写回,数据库中的值是4,B也写回,数据库中的值也是4。虽然3+2=5。这样一来,一票优势就会落空。这叫做丢失更新问题

您可以使用前面提到的锁来防止这种情况。在更新并释放锁之前,As B无法从表中读取。之后,它将读取4而不是3,因此写回5,这是正确的

但最好是在一次更新中完成,比如

UDPATE votes
       SET votes = votes + 1
       WHERE article = @some_id;
也就是说,无论应用程序认为数据库中的实际值是什么,都会增加数据库中的实际值

如果事务具有适当的隔离级别,数据库将自行负责锁定,从而防止并发事务使用脏的、过时的数据进行更新


我建议您多读一点关于事务、隔离级别和锁定的内容,以充分理解这个问题。

有两种解决方案:

如果确实需要将值加载到应用程序中并在其中递增,然后再写回,请在选择值之前在表上获得适当的锁。完成值后释放锁。要么是因为取消投票,要么是因为重写了实际的追加投票

否则,并发实例B可以读取相同的值,并在第一个实例a之后将其写回。假设两者都读取3。两者都将其增加到4。然后A在B之前写回,数据库中的值是4,B也写回,数据库中的值也是4。虽然3+2=5。这样一来,一票优势就会落空。这叫做丢失更新问题

您可以使用前面提到的锁来防止这种情况。在更新并释放锁之前,As B无法从表中读取。之后,它将读取4而不是3,因此写回5,这是正确的

但最好是在一次更新中完成,比如

UDPATE votes
       SET votes = votes + 1
       WHERE article = @some_id;
也就是说,无论应用程序认为数据库中的实际值是什么,都会增加数据库中的实际值

如果事务具有适当的隔离级别,数据库将自行负责锁定,从而防止并发事务使用脏的、过时的数据进行更新


我建议您多读一点关于事务、隔离级别和锁定的内容,以充分了解这个问题。

我的强烈建议是在投票表中记录每个向上投票和向下投票:

然后,您可以根据需要汇总投票。随着时间的推移,你可以看到投票的趋势。你可以确保某人在过去投票时可以取消投票

而且,插入到表中不会有不同用户相互干扰的风险


缺点是总结结果需要更多的时间。当问题出现时,您可以对其进行优化。

我的强烈建议是,在投票表中记录每一次向上投票和向下投票:

然后,您可以根据需要汇总投票。随着时间的推移,你可以看到投票的趋势。你可以确保某人在过去投票时可以取消投票

而且,插入到表中不会有不同用户相互干扰的风险


缺点是总结结果需要更多的时间。当问题出现时,您可以对其进行优化。

要获得一些灵感,您可能需要查看SEDE:尽管模型已针对数据转储进行了更改要获得一些灵感,您可能需要查看SEDE:尽管模型已针对数据转储进行了更改