每次保存某个模型的记录时,我都需要保存一个参考号,该参考号应由10个数字组成,前8个数字与创建者ID和日期有关,但后2个数字应与从00开始至99结束的递增数字,此计数应每天重置。
例如:
Records created the same day:
SD01011800
GF01011801
MT01011802
...
GH01011899
------------------------------------------------------------------------------
Records created the next day:
SD02011800
GF02011801
MT02011802
...
GH02011899
前2个字母是姓名的缩写,后2个是当日,下2个当月,下2个当年,下2个递增数字(从0到99,每天重置)
每个参考也必须是唯一的。 我缺少最后两位数字的部分,关于如何授予它的任何想法吗? 感谢您的阅读。
答案 0 :(得分:1)
其中前2个字母是名称的缩写,后2个是当日,下2个当月,下2个当年,后2个递增数字(从0到99,每天重置)。
As folks in the comments have pointed out,这假设每天最多有100个条目,并且在2100年会出现问题。一个问题比另一个问题更为紧迫。也许如果您超过100,就可以开始使用字母了吗?
每个参考文献都必须唯一。
对于全局唯一标识符UUID,通常是通用唯一标识符。如果您可以更改此要求,它将既简单(数据库已经支持UUID),也更健壮(UUID不限于每天100个),并且更加安全(它们不会泄漏有关被识别事物的信息)。 / p>
假设您无法更改需求,则可以通过将当天的现有行数相加得出下一个数字。
select count(id)
from stuff
where date(created_at) == date(NOW());
但是,如果两个进程都同时插入新记录并获得相同的下一个编号,则会出现问题。如果您期望每天只使用100个,则可能性很小,但仍然可以实现。
Process 1 Process 2 Time
select count(id) ... 1
select count(id) ... 2
insert into stuff ... 3
insert into stuff... 4
一笔交易无法挽救您。您可以在整个表上获得排他锁,但这是危险且缓慢的。相反,您可以使用an advisory lock进行此操作。只要确保所有写入新记录的代码都使用相同的咨询锁即可。
Stuff.with_advisory_lock(:new_stuff_record) do
...
end
或者,将每日ID存储在列中。添加数据库触发器以在插入时加1。午夜安排的作业将其设置回0。
答案 1 :(得分:1)
我将假设您的班级名为Record
,并且它具有名为reference_number
的属性。
在这种情况下,您可以使用以下方法来获取最后两位数字。
def fetch_following_two_last_digits
if Record.last.created_at < Time.current.beginning_of_day
"00"
else
(Record.last.reference_number.last(2).to_i + 1).to_s
end
end
还要假设您每天从未达到100条记录。否则,您将最后三位数。