给定一个唯一折扣代码列表,如何每个都只发送一次
Given a list of unique discount codes, how to send each one only once
我想知道解决此问题的最佳方法:给定电子商务网站的 500 个唯一折扣代码的预生成列表,我如何确保前 500 个用户中的每个人都获得折扣代码每个收到一个唯一的?电子商务站点将使用存储在其数据库中的折扣代码列表向单独的服务器发出异步请求。该服务器的工作是确保每个折扣代码仅按收到请求的时间顺序发回一次。
由于这似乎是一个相当原始的问题,我想知道是否有一种聪明而优雅的方法可以用相对较低的工作量来做到这一点。
一个简单的方法是收集您的代码并在 select 删除项目时删除它们。这是 .findAndModify()
.
的简单示例
一个基本的集合示例:
db.codes.insert([
{ "a": 1 },
{ "a": 2 },
{ "a": 3 }
])
发出一个.findAndModify()
:
db.codes.findAndModify({
"query": {},
"remove": true,
"new": false
})
Returns:
{ "_id" : ObjectId("550caf3f7d9c3dc0eab83334"), "a" : 1 }
集合的新状态是:
{ "a": 2 }
{ "a": 3 }
因此,当检索到文档时,它会从集合中删除,以防止进一步 selection。由于 .findAndModify()
是一个原子操作,没有其他请求可以看到同一个文档,每个请求都会得到它自己唯一的响应。
如果你的数据库有原子事务,这没问题。只需创建一个包含 2 个字段的 table discount
,code
(varchar 宽度足以容纳代码)和 used
(布尔值),由 used
索引,然后通过 code
。最初 INSERT
500 行,当然每行 used = false
。每当请求到来时,只需 SELECT min(code) FROM discount FOR UPDATE WHERE NOT used
,然后是 UPDATE discount SET used = true WHERE NOT used AND code = <that code>
,所有这些都在一个数据库事务中。 (更新的 NOT used
部分不是正确性所必需的,但可以通过启用索引来加快速度。)
如果争用是个问题(我看不出 500 个请求会怎样,但也许会这样),然后添加一个整数 id
字段,其中包含一个介于 1 和500 到 table。然后在每个请求中,选择一个介于 1 和 500 之间的随机数 r
,以及 SELECT min(code) FROM discount FOR UPDATE WHERE NOT used AND (id >= <r> OR id + 500 >= <r>)
。括号中的条件确保搜索将 "wrap around" 到较低编号的折扣,前提是(且仅当)所有折扣 >= r
已被采用。
我想知道解决此问题的最佳方法:给定电子商务网站的 500 个唯一折扣代码的预生成列表,我如何确保前 500 个用户中的每个人都获得折扣代码每个收到一个唯一的?电子商务站点将使用存储在其数据库中的折扣代码列表向单独的服务器发出异步请求。该服务器的工作是确保每个折扣代码仅按收到请求的时间顺序发回一次。
由于这似乎是一个相当原始的问题,我想知道是否有一种聪明而优雅的方法可以用相对较低的工作量来做到这一点。
一个简单的方法是收集您的代码并在 select 删除项目时删除它们。这是 .findAndModify()
.
一个基本的集合示例:
db.codes.insert([
{ "a": 1 },
{ "a": 2 },
{ "a": 3 }
])
发出一个.findAndModify()
:
db.codes.findAndModify({
"query": {},
"remove": true,
"new": false
})
Returns:
{ "_id" : ObjectId("550caf3f7d9c3dc0eab83334"), "a" : 1 }
集合的新状态是:
{ "a": 2 }
{ "a": 3 }
因此,当检索到文档时,它会从集合中删除,以防止进一步 selection。由于 .findAndModify()
是一个原子操作,没有其他请求可以看到同一个文档,每个请求都会得到它自己唯一的响应。
如果你的数据库有原子事务,这没问题。只需创建一个包含 2 个字段的 table discount
,code
(varchar 宽度足以容纳代码)和 used
(布尔值),由 used
索引,然后通过 code
。最初 INSERT
500 行,当然每行 used = false
。每当请求到来时,只需 SELECT min(code) FROM discount FOR UPDATE WHERE NOT used
,然后是 UPDATE discount SET used = true WHERE NOT used AND code = <that code>
,所有这些都在一个数据库事务中。 (更新的 NOT used
部分不是正确性所必需的,但可以通过启用索引来加快速度。)
如果争用是个问题(我看不出 500 个请求会怎样,但也许会这样),然后添加一个整数 id
字段,其中包含一个介于 1 和500 到 table。然后在每个请求中,选择一个介于 1 和 500 之间的随机数 r
,以及 SELECT min(code) FROM discount FOR UPDATE WHERE NOT used AND (id >= <r> OR id + 500 >= <r>)
。括号中的条件确保搜索将 "wrap around" 到较低编号的折扣,前提是(且仅当)所有折扣 >= r
已被采用。