如何在 Firestore 中构建抽奖应用程序的数据?
How to structure the data of a lottery draw application in Firestore?
我正在使用 react-native + Cloud Firestore 开发一个应用程序,旨在为每个填写表单的用户生成随机 numbers/tickets。这些号码将允许用户参与电子彩票并争夺促销奖品。
这些数字应该按系列分隔,例如:
Series 1 - numbers can range from 0 to 99,999 thousand.
Series 2 - numbers can range from 0 to 99,999 thousand.
Series N - numbers can range from 0 to 99,999 thousand.
系统要求是:
- 必须维护为每个用户生成的系列和编号(为客户保存的编号);
- 每个促销还必须包含生成的数字和系列(促销中生成的数字,总计);
在 Cloud Firestore 的第一个结构中,我们创建了如下结构:
Promotion - Series - Number
(random doc) - 01 - 00131 ...
(random doc) - 01 - 97879 ...
(random doc) - 09 - 99999
Promotion是一个集合,Series是promotion子集合,Number是Series子集合。
但是,通过这种方式,在firestore中进行了很多查询API,例如,获取一个系列内要生成的可用编号,以便生成新编号。
我们发现的另一种方法是数字的子集合可以是 Series 集合中的数组。这将减少查询。
100,000 个数字数组是否会超过最大 1mb 文档大小?
可以用一个带map的结构体,比如写成beyond number其他属性如下:
Promotion - Series - Numbers: Map?
"100,000 个数字数组会超过最大 1mb 文档大小吗?"
数组中的每个数字都将消耗 8 bytes,因此仅数组值将约为 800KB,然后加上文档和字段名称的一些开销,您应该仍在限制范围内。
但是,您需要确保进入 UI 中的单字段索引并为数组字段创建一个 exemption,因为每个数组值消耗 2 个索引条目(以及整个array 消耗 2 本身),所以你肯定会超过每个文档限制的 20K 索引条目。注意:这意味着您将无法查询数组。
”但是,通过这种方式在firestore中进行了很多查询API,例如,获取一个系列内要生成的可用数字,以便新数字可以生成。"
我猜这 2 个不成文的假设:
- 同一号码不能分配给多个客户
- 大多数(如果不是所有)系列中的号码都会被分配
如果 2 不正确,您可以只生成一个数字,查看它是否存在,如果存在则重新生成并重试。如果要分配大部分或所有号码,这将变得更加昂贵。
另一种方法是采用混合方法。
对于 100,000 个数字,创建 1000 个文档,每个文档拥有 100 个数字,并将这 100 个数字存储在一个名为 ticket_number
:
的数组中
/promotions/<series number>/numbers/<nnnn>
--> ticket_number: [nnnn01, nnnn02, ..., (nnnn+1)00]
在每个文档上都有一个名为 available
的布尔字段,如果该范围内的数字仍然可用,则该字段设置为 true
。如果不是,请删除该字段或将其设置为 false
使用从full == true
这些文件中随机得到一个文件select。从此文档中 select 数组中的随机票号,将其删除并更新文档。
最终,所有值都将以这种方式 selected,同时只需要为每张票读取和写入一个文档(以及将 selected number/series 写入一个单独的文档)。
写入速率注意事项
请注意,建议每个文档的最大持续速率为每秒 1 次写入。在单文档方法中,这意味着数字分配缓慢或某些上游批处理机制。
通过使用混合方法,您可以跨更多文档进行分片以提高写入率。在我上面给出的示例中,这是每秒 1000 次写入。
我正在使用 react-native + Cloud Firestore 开发一个应用程序,旨在为每个填写表单的用户生成随机 numbers/tickets。这些号码将允许用户参与电子彩票并争夺促销奖品。
这些数字应该按系列分隔,例如:
Series 1 - numbers can range from 0 to 99,999 thousand.
Series 2 - numbers can range from 0 to 99,999 thousand.
Series N - numbers can range from 0 to 99,999 thousand.
系统要求是:
- 必须维护为每个用户生成的系列和编号(为客户保存的编号);
- 每个促销还必须包含生成的数字和系列(促销中生成的数字,总计);
在 Cloud Firestore 的第一个结构中,我们创建了如下结构:
Promotion - Series - Number
(random doc) - 01 - 00131 ...
(random doc) - 01 - 97879 ...
(random doc) - 09 - 99999
Promotion是一个集合,Series是promotion子集合,Number是Series子集合。
但是,通过这种方式,在firestore中进行了很多查询API,例如,获取一个系列内要生成的可用编号,以便生成新编号。
我们发现的另一种方法是数字的子集合可以是 Series 集合中的数组。这将减少查询。
100,000 个数字数组是否会超过最大 1mb 文档大小? 可以用一个带map的结构体,比如写成beyond number其他属性如下:
Promotion - Series - Numbers: Map?
"100,000 个数字数组会超过最大 1mb 文档大小吗?"
数组中的每个数字都将消耗 8 bytes,因此仅数组值将约为 800KB,然后加上文档和字段名称的一些开销,您应该仍在限制范围内。
但是,您需要确保进入 UI 中的单字段索引并为数组字段创建一个 exemption,因为每个数组值消耗 2 个索引条目(以及整个array 消耗 2 本身),所以你肯定会超过每个文档限制的 20K 索引条目。注意:这意味着您将无法查询数组。
”但是,通过这种方式在firestore中进行了很多查询API,例如,获取一个系列内要生成的可用数字,以便新数字可以生成。"
我猜这 2 个不成文的假设:
- 同一号码不能分配给多个客户
- 大多数(如果不是所有)系列中的号码都会被分配
如果 2 不正确,您可以只生成一个数字,查看它是否存在,如果存在则重新生成并重试。如果要分配大部分或所有号码,这将变得更加昂贵。
另一种方法是采用混合方法。
对于 100,000 个数字,创建 1000 个文档,每个文档拥有 100 个数字,并将这 100 个数字存储在一个名为 ticket_number
:
/promotions/<series number>/numbers/<nnnn>
--> ticket_number: [nnnn01, nnnn02, ..., (nnnn+1)00]
在每个文档上都有一个名为 available
的布尔字段,如果该范围内的数字仍然可用,则该字段设置为 true
。如果不是,请删除该字段或将其设置为 false
使用full == true
这些文件中随机得到一个文件select。从此文档中 select 数组中的随机票号,将其删除并更新文档。
最终,所有值都将以这种方式 selected,同时只需要为每张票读取和写入一个文档(以及将 selected number/series 写入一个单独的文档)。
写入速率注意事项
请注意,建议每个文档的最大持续速率为每秒 1 次写入。在单文档方法中,这意味着数字分配缓慢或某些上游批处理机制。
通过使用混合方法,您可以跨更多文档进行分片以提高写入率。在我上面给出的示例中,这是每秒 1000 次写入。