在表中生成介于1-999之间的唯一主键数字。
我有一个问题,我不确定如何优雅地解决它。
背景信息
我有一个小部件表。每个小部件都分配了一个 ID,从一定范围的数字中分配,比如说从1到999。数值1到999在我的数据库中保存为“lower_range”和“upper_range”,保存在一个名为“config”的表中。 当用户请求使用我的网络应用程序创建新的小部件时,我需要能够执行以下操作:
- 使用lua的math.random函数或可能是sqlite中的随机数生成器生成1到999之间的随机数(到目前为止,在我的测试中,lua的math.random总是返回相同的值...但这是一个不同的问题)
- 做一个select语句,查看是否已经存在分配了这个数字的小部件...
- 如果没有,创建新的小部件。
- 否则重复这个过程,直到找到一个尚未使用的数字。
问题
我看到上面的逻辑存在两个问题:
- 该算法可能需要很长时间,因为我必须一直搜索,直到找到唯一的值。
- 我如何防止同时请求新小部件编号的请求生成相同的值?
任何建议都将不胜感激。 谢谢
创建一张表来存储键和 'used' 属性。
CREATE TABLE KEYS
("id" INTEGER, "used" INTEGER)
;
然后使用以下语句来查找一个新的键
select id
from KEYS
where used = 0
order by RANDOM()
limit 1
不要生成随机数,只需从随机顺序的列表中选择数字。
例如,制作数字1-999的列表。使用Fisher-Yates 或等效方法(参见 C#中的随机列表,即使您不使用C#)洗牌该列表。
现在,您可以跟踪最近使用的索引进入列表中。 (应该只会发生列表洗牌一次,然后您存储和重复使用结果)。
粗略的伪代码:
如果配置文件不包含索引列表
创建包含数字1-999的列表
使用Fisher-Yates洗牌该列表
//列表现在看起来像0,97,251,3,...
将列表写入配置文件
设置“上次使用的索引”为0并写入配置文件
结束如果
使用此方法:
NextPK = myList[last-index-used]
last-index-used = last-index-used + 1
将“上次使用的索引”写入配置文件
将下面翻译成中文并且保留原本的 markdown 格式
Generate your random numbers ahead of time and store them in a table; make sure the numbers are unique. Then when you need to get the next number, just check how many have already been assigned and get the next number from your table. So, instead of
- Generate a number between 1-999
- Check if it's already assigned
- Generate a new number, and so on.
do this:
- Generate array of 999 elements that have values 1-999 in some random order
- Your `GetNextId` function becomes `return ids[currentMaxId+1]`
To manage simultaneous requests, you need to have some resource that generates a proper sequence. The easiest is probably to use a key in your widget table as the index in the `ids` array. So, add a record to the `widgets` table first, get its key and then generate widget ID using `ids[key]`.
提前生成您的随机数并将其存储在一张表中,确保数字是唯一的。然后,在您需要获取下一个数字时,只需检查已分配的数字数量,并从您的表中获取下一个数字。因此,替代以下步骤:
- 生成一个介于1-999之间的数字
- 检查它是否已被分配
- 生成一个新的数字,以此类推
执行以下步骤:
- 生成拥有999个元素的数组,这些元素在某种随机顺序下具有值1-999
- 您的
GetNextId函数变成了return ids[currentMaxId+1]
为了管理同时请求,您需要拥有一些资源来生成适当的序列。最简单的方法可能是将您的widget表中的一个键用作ids数组中的索引。因此,首先向widgets表添加一条记录,获取其键,然后使用ids[key]生成widget ID。
为了同时获取并标记一个 ID(在 Declan_K 的答案上进行扩展):
replace into random_sequence values ((select id from random_sequence where used=0 order by random()), 1);
select id from random_sequence where rowid = last_insert_rowid();
当你用完了“未使用”的序列表条目时,select 将返回“空白”
我使用 replace into,因为我看不到 update 有一个 last_insert_rowid() 的等效函数。
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
你可以使用 SQL 创建一个主键,每次向数据库中添加一行,该主键都会自动增加一。