php mysql 提供独特的凭证

标签 php mysql

我正在设计一个提供优惠券(序列号)的网站。所有优惠券代码都生成并保存在这样的表中,而不是在线生成:

 v_id             voucher                status (used?)
-------------------------------------------------------
  1              abcdefgabcdefg1             0
  2              abcdefgabcdefg2             0
  3              abcdefgabcdefg3             0
  4              abcdefgabcdefg4             0

成功付款后,我应该向最终用户显示未使用的(状态:0)凭证,但我不确定如何执行此操作,因为该网站可能具有很高的流量,因此多个人可能会在同一毫秒内访问该网站,例如,我不能只使用:

SELECT * FROM table WHERE status=0 LIMIT 0,1;

然后更新它:

UPDATE table SET status=1 WHERE v_id=....

因为两个人可能同时访问,所以我们为两个人提供 v_id=1 序列号(相同的序列号)。

确保显示唯一序列号的最佳方法是什么?

最佳答案

免责声明

此答案中的代码尚未经过测试。应调整每个列名称和表名称以适合您的代码。发布此答案是为了说明如何处理并发性和唯一性。

问题

确保一张优惠券只能使用一次

解决方案

我们将创建另一个表,并用已使用的优惠券填充该表。

提到的表将有一个 foreign keyvoucher表,通过其主键引用特定凭证,它将具有相同的列 unique 。这使得优惠券 100% 安全,不会被多次使用

表结构

CREATE TABLE vouchers_uised (
    id int unsigned not null auto_increment,
    voucher_id int unsigned not null,
    unique(voucher_id),
    foreign key (voucher_id) references `vouchers` (`id`) on delete cascade
) ENGINE = InnoDB;

逻辑

使用优惠券时,需输入vouchers_used table 。这是一个简单的表格,因此您所需要做的就是插入一列。

INSERT INTO vouchers_used SET voucher_id = 1;

成功

如果成功,PHP 会将查询/准备语句的结果解释为 true

失败时

失败将发出信号 SQLSTATE代码 23000这是 DUPLICATE KEY 的代码。如果您使用PDO在异常模式下,捕获异常并检查 $e->getCode() == '23000 ;`将允许您检查查询是否因优惠券已被使用而失败

如何列出可用优惠券

有两种方法可以处理可用优惠券。

第一个是尝试 JOIN包含已用优惠券的表格,并过滤掉 vouchers_used不存在的优惠券表

第二个是帮助自己使用您想要使用的标志,is_availablevouchers table 。您可以使用一个更新的小触发器来帮助自己 vouchers每次向表添加一条记录到 vouchers_used table 。这样你就不必太担心 PHP 代码中的逻辑

触发代码:

DELIMITER $$

CREATE
    TRIGGER `vouchers_used_after_insert` AFTER INSERT
    ON `vouchers_used`
    FOR EACH ROW BEGIN
    UPDATE vouchers SET is_used = 1 WHERE id = NEW.voucher_id;
    END$$

DELIMITER ;

显示可用优惠券

要显示前端可用的优惠券,一个简单的查询就足够了:

SELECT * FROM vouchers WHERE is_used = 0;

如果同时使用优惠券,unique约束将阻止用户做任何有损数据完整性的事情。您的工作是相应地解释来自数据库的消息,并同时指示用户优惠券已被使用。

关于php mysql 提供独特的凭证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41062556/

相关文章:

java - Hibernate限制中限制 'equals id'区分大小写

mysql - 将特定行从一个表更新到另一个表

php - 未获取 Laravel 外键表 [错误]

python:更新mysql表

php - Android - 在数据库调用时维护数据库用户名和密码的更好方法

php - 在创建新行条目时从 mysql 行中检索时间戳

PHP mail() BCC - 仅显示 To : header 中的最终收件人地址

mysql - 递归 MySql 触发器不起作用

php - 编程中如何做好验证?

php - php 中的 cfhttp "POST"