abp icon indicating copy to clipboard operation
abp copied to clipboard

Sequential Guids

Open lisheng741 opened this issue 3 years ago • 5 comments

Abp's algorithm fininshes in milliseconds and the timestamp generated in the case of high concurrency may be the same, resulting in the Guid generated at the same time not being sequential. See: https://github.com/abpframework/abp/issues/11453

lisheng741 avatar Jul 30 '22 10:07 lisheng741

I tested it on Sql Server, MySQL and MongoDB it works perfectly thank you

ahmetfarukulu avatar Jul 30 '22 13:07 ahmetfarukulu

I tested it on Sql Server, MySQL and MongoDB it works perfectly thank you

I'm sorry that yesterday's algorithm was still flawed. Now, I fixed it.

lisheng741 avatar Jul 31 '22 09:07 lisheng741

About the sorting order of MSSQL Guids

MSSQL and System.Data.SqlTypes.SqlGuid sort first by the last 6 Data4 bytes, left to right, then the first two bytes of Data4 (again, left to right), then Data3, Data2, and Data1 right to left.

See: richardtallent/RT.Comb#icombprovider

MSSQL: rrrrrrrr-rrrr-Mxdr-Nddd-dddddddddddd
Block: 1        2    3    4    5
Data : 1        2    3    4

Data4 = Block4 + Block5
sorting order: Block5 >> Block4 >> Block3 >> Block2 >> Block1

lisheng741 avatar Jul 31 '22 10:07 lisheng741

1、一定的时间以后,新产生的 Guid 与旧 Guid 不连续的问题

2022年7月30日提交的代码,产生的 Guid 如:

74F98FF5-171C-BFFD-08DA-724214AEE378

其中 08DA-724214AEE378 为时间戳,转为十进制为 637947925366760312,代表的时间为: 2022-07-30 23:42:16.

当时间戳到达 08DB000000000000,Guid 如下:

74F98FF5-171C-BFFD-08DB-000000000000

转为十进制为 638103772203057152,代表的时间为:2023-01-27 08:47:00.

根据 Sql Server Guid 的排序规则:

74F98FF5-171C-BFFD-08DB-000000000000 < 74F98FF5-171C-BFFD-08DA-724214AEE378

不满足我们的预期。

2022年7月31日提交的代码,可以解决这个问题,并且兼容过往版本产生的连续 Guid.

2、RFC 4122 Version 4

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

M = RFC version, in this case '4' for random UUID
N = RFC variant (plus other bits), where N is one of 8,9,A, or B, in this case 8 for variant 1

lisheng741 avatar Jul 31 '22 12:07 lisheng741

Backward compatibility.

The Guid generated by the modified algorithm is sequential with that generated by the original algorithm.

SequentialAsString or SequentialAsBinary

# Before
3a049123-74ad-23ec-dad0-d464099ef66d

# Now
3a056aac-8aa7-07a6-7356-c645aceb8973

SequentialAtEnd

# Before
9D5CAA29-196B-733F-F14E-3A0569C13460

# Now
EC4F072A-7C85-5199-1E13-3A056AA7E0CE

lisheng741 avatar Aug 01 '22 09:08 lisheng741

hi @lisheng741

What do you think about https://github.com/jhtodd/SequentialGuid/issues/1 ?

maliming avatar Nov 08 '22 08:11 maliming

hi @lisheng741

What do you think about jhtodd/SequentialGuid#1 ?

Hi, maliming

About jhtodd/SequentialGuid#1:

When the database is stored, the primary keys are stored sequentially, so even if the in-memory GUids are not contiguous, the B+ tree for its clustered index is reconstructed when stored in the database.

I think: as long as the Guid as the primary key is continuous overall, even if it is not continuous for a short time, it does not matter.

Just as jhtodd says:

It's mostly situations like your example code where a loop is doing nothing but generating a whole lot of GUIDs at once where it can become an issue -- and even then, probably not a huge one.

Unless:

1、There are also continuous requirements when other fields are stored in the database;

2、Each time the Guid is obtained, it is strictly required to be continuous with the last time;

....

All in all:

The original method is generally not a problem to use, you can roll back to the original method, it is very useful.

Thank you very much. In the process of solving this problem, I really learned a lot and also realized that I was lacking in many things.

lisheng741 avatar Nov 08 '22 12:11 lisheng741

If you're interested in sequential GUids, You can read this article, But it only in Chinese: ASP.NET Core generates sequential GUids

lisheng741 avatar Nov 08 '22 12:11 lisheng741

Thanks again.

maliming avatar Nov 08 '22 12:11 maliming