解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
|
# Snowflake Ñ©»¨Ë㷨ʹÓÃÊÖ²á
±¾Îĵµ»ùÓÚÔ´Âë `NewLife.Core/Data/Snowflake.cs` Óë²âÊÔ `XUnitTest.Core/Data/SnowflakeTests.cs`£¬ÓÃÓÚ˵Ã÷ `Snowflake`£¨Ñ©»¨Ëã·¨·Ö²¼Ê½ Id Éú³ÉÆ÷£©µÄÉè¼Æ¡¢Ó÷¨Óë×¢ÒâÊÂÏî¡£
> ¹Ø¼ü´Ê£ºµ¥Àý¡¢WorkerId¡¢Ê±¼ä´Á¡¢ÐòÁкš¢Ê±¼ä»Ø²¦¡¢¼¯Èº·ÖÅ䣨Redis£©¡£
---
## 1. ¸ÅÊö
`Snowflake` ÓÃÒ»¸ö 64 bit µÄ `Int64` ×÷Ϊȫ¾ÖΨһ Id¡£
λ·ÖÅ䣺
- 1 bit£º±£Áô£¨·ûºÅ룩
- 41 bit£ºÊ±¼ä´Á£¨ºÁÃ룩
- 10 bit£º¹¤×÷½Úµã£¨`WorkerId`£¬0~1023£©
- 12 bit£ºÐòÁкţ¨0~4095£©
Éú³ÉµÄ Id ¾ß±¸ÒÔÏÂÌØµã£º
- ´óÌåÇ÷ÊÆ×ÔÔö£¨°´Ê±¼äÍÆ½ø£©
- ͬһºÁÃëÄÚ¿ÉÉú³É×î¶à 4096 ¸ö Id
- **ÔÚͬһ¸ö `Snowflake` ʵÀýÄÚ**¿É±£Ö¤²»Öظ´
ÖØÒªÔ¼Êø£º
- **ÒµÎñÄÚ±ØÐëÈ·±£µ¥Àý**¡£Èô²¢·¢³¡¾°´æÔÚ¶à¸ö `Snowflake` ʵÀý£¬²¢ÇÒ `WorkerId` Ïàͬ£¬Ôò¿ÉÄܲúÉúÖØ¸´ Id¡£
---
## 2. ºËÐĸÅÄî
### 2.1 `StartTimestamp`£¨Æðʼʱ¼ä´Á£©
- ÊôÐÔ£º`public DateTime StartTimestamp { get; set; }`
- ĬÈÏÖµ£º`UTC 1970-01-01` תΪ±¾µØÊ±¼ä£¨`DateTimeKind.Local`£©
ÓïÒåÒªµã£º
- `Snowflake` »á°Ñ²ÎÓë¼ÆËãµÄʱ¼äת»»µ½ `StartTimestamp` ËùÊôÊ±Çø£¬È»ºó×ö²îµÃµ½ºÁÃëÊý¡£
- ĬÈÏʹÓñ¾µØÊ±¼ä£¬ÊÇΪÁË·½±ã½âÎöÑ©»¨ Id ʱֱ½ÓµÃµ½±¾µØÊ±¼ä£¬²¢×î´ó¼æÈÝÒÑÓÐÒµÎñ£¨ÓÈÆäÊǰ´±¾µØÈÕÆÚ·Ö±í/·ÖÇøµÄ³¡¾°£©¡£
ʹÓý¨Ò飺
- `StartTimestamp` **±ØÐëÔÚÊ״ε÷Óà `NewId()` ǰÉèÖÃ**£¬Ê×´ÎÉú³ÉºóÔÙÐ޸IJ»»áÓ°ÏìÒѳõʼ»¯ÊµÀý£¨ÒòΪ³õʼ»¯¹ý³ÌÖ»×öÒ»´Î£©¡£
### 2.2 `WorkerId`£¨¹¤×÷½Úµã Id£©
- ÊôÐÔ£º`public Int32 WorkerId { get; set; }`
- ·¶Î§£º0~1023£¨10 룩
˵Ã÷£º
- ÔÚ·Ö²¼Ê½ÏµÍ³ÄÚ£¬`WorkerId` µÄÈ«¾ÖΨһÐÔ¾ö¶¨ÁË¿ç½ÚµãÊÇ·ñ»á²úÉúÖØ¸´ Id¡£
- ½öÒÀ¿¿Ä¬ÈÏËã·¨£¨IP/½ø³Ì/Ị̈߳©**ÎÞ·¨¾ø¶Ô±£Ö¤Î¨Ò»**£¬¸ßÒªÇ󳡾°½¨ÒéÍⲿÏÔʽ·ÖÅä¡£
### 2.3 `Sequence`£¨ÐòÁкţ©
- ÊôÐÔ£º`public Int32 Sequence => _sequence;`
- ·¶Î§£º0~4095£¨12 룩
˵Ã÷£º
- ͬһºÁÃëÄÚͨ¹ýµÝÔöÐòÁкű£Ö¤Î¨Ò»¡£
- ÐòÁÐÒç³ö£¨³¬¹ý 4095£©Ê±£¬Ëã·¨»áÂß¼ÉÏÍÆ½øµ½ÏÂÒ»ºÁÃë¼ÌÐøÉú³É¡£
---
## 3. WorkerId ³õʼ»¯ÓÅÏȼ¶
`Snowflake` ÔÚÊ×´ÎÉú³É Id ʱ»á×Ô¶¯Ö´ÐÐÒ»´Î³õʼ»¯£¨`Initialize()`£©£¬°´ÓÅÏȼ¶¾ö¶¨ `WorkerId`£º
1. Èç¹ûʵÀý `WorkerId > 0`£ºÊ¹ÓÃʵÀýÖµ
2. ·ñÔòÈç¹û `Snowflake.GlobalWorkerId > 0`£ºÊ¹Óà `GlobalWorkerId & 1023`
3. ·ñÔòÈç¹û `Snowflake.Cluster != null`£ºµ÷Óà `JoinCluster(Cluster)` ´Ó¼¯Èº·ÖÅä
4. ·ñÔò£ºÊ¹ÓÃĬÈÏËã·¨Éú³É£¨»ùÓÚ IP ÅÉÉúµÄʵÀýºÅ + ½ø³Ì/Ị̈߳©
×¢Ò⣺
- ´úÂëÖÐʹÓõÄÊÇÅÐ¶Ï `WorkerId <= 0`£¬Òò´Ë **`WorkerId=0` »á±»ÊÓΪ¡°Î´ÉèÖá±²¢¼ÌÐø×ߺóÐø²ßÂÔ**¡£ÈôÄãÏ£Íû¹Ì¶¨Îª 0£¬ÐèÒª×ÔÐÐÈ·±£²»Òª´¥·¢³õʼ»¯¸²¸Ç£¨Ò»°ã²»½¨Ò飩¡£
---
## 4. API ËÙ²é
### 4.1 `Int64 NewId()`
»ùÓÚµ±Ç°Ê±¼äÉú³ÉÏÂÒ»¸ö Id¡£
ÐÐΪҪµã£º
- ʹÓà `DateTime.Now`£¨±¾µØÊ±¼ä£©£¬²¢Í¨¹ý `ConvertKind` ת»»µ½ `StartTimestamp` µÄÊ±Çø¡£
- ´¦Àíʱ¼ä»Ø²¦£º
- Èô¼ì²âµ½Ê±¼ä»Ø²¦Çһز¦·ù¶È´óÓÚ `MaxClockBack`£¨Ô¼ 1 Сʱ + 10 Ã룩£¬Å׳ö `InvalidOperationException`
- ·ñÔòʹÓÃÉÏÒ»´Îʱ¼ä´Á¼ÌÐøÉú³É£¨±£³Öµ¥ÊµÀýΨһÐÔ£©
ÊÊÓó¡¾°£º
- ³£¹æÒµÎñÖ÷¼üÉú³É£¨×î³£Óã©¡£
### 4.2 `Int64 NewId(DateTime time)`
»ùÓÚÖ¸¶¨Ê±¼äÉú³É Id£¨Ð¯´øµ±Ç°ÊµÀýµÄ `WorkerId` ÓëÐòÁкţ©¡£
×¢Ò⣺
- ÈôÄãΪͬһ¸ö¡°Ö¸¶¨ºÁÃëʱ¼ä¡±Éú³É³¬¹ý 4096 ¸ö Id£¬Ôò¿ÉÄÜÖØ¸´£¨ÒòΪÐòÁкÅÖ»ÓÐ 12 룬»áȡ죩¡£
ÊÊÓó¡¾°£º
- ÐèÒªÓÃÒµÎñʱ¼ä¹¹Ôì²åÈë Id£¨ÀýÈç°´²É¼¯Ê±¼äÂä¿â£©¡£
### 4.3 `Int64 NewId(DateTime time, Int32 uid)`
»ùÓÚÖ¸¶¨Ê±¼äÉú³É Id£¬Ê¹Óà `uid` µÄµÍ 10 λ×÷Ϊ `WorkerId`£¨1024 ·Ö×飩£¬ÈÔ±£Áô 12 λÐòÁкš£
ÊÊÓó¡¾°£º
- ÎïÁªÍøÊý¾Ý²É¼¯£ºÃ¿ 1024 ¸ö´«¸ÐÆ÷Ϊһ×飬ÿ×éÿºÁÃë¿ÉÉú³É×î¶à 4096 ¸ö Id¡£
×¢Ò⣺
- Èôͬһ·Ö×éͬһºÁÃëÉú³É³¬¹ý 4096 ¸ö Id£¬Ôò¿ÉÄÜÖØ¸´¡£
### 4.4 `Int64 NewId22(DateTime time, Int32 uid)`
»ùÓÚÖ¸¶¨Ê±¼äÉú³É Id£¬Ê¹Óà 22 λҵÎñ Id£¨`uid & ((1<<22)-1)`£©£¬²»ÔÙ±£ÁôÐòÁкš£
ÊÊÓó¡¾°£º
- ÎïÁªÍøÊý¾Ý²É¼¯£ºÃ¿ 4,194,304 ¸ö´«¸ÐÆ÷Ò»×飬ÿ×éÿºÁÃë×î¶à 1 ¸ö Id¡£
- ³£ÓÃÓÚÅäºÏ upsert£ºÍ¬Ò»ºÁÃëͬһ´«¸ÐÆ÷д¶àÐÐÊý¾Ýʱֻ±£ÁôÒ»ÐС£
×¢Ò⣺
- ͬһҵÎñ id ÔÚͬһºÁÃëÄÚÉú³É¶à¸ö Id »áÖØ¸´£¨ÒòΪûÓÐÐòÁкţ©¡£
### 4.5 `Int64 GetId(DateTime time)`
°Ñʱ¼äת»»Îª¡°½ö°üº¬Ê±¼ä²¿·Ö¡±µÄ Id£¨²»´ø `WorkerId` ÓëÐòÁкţ©¡£
ÊÊÓó¡¾°£º
- ¹¹Ôìʱ¼äƬ¶Î²éѯ£º½«Ê±¼äÇø¼äת»»ÎªÑ©»¨ Id Çø¼ä½øÐз¶Î§²éѯ¡£
### 4.6 `Boolean TryParse(Int64 id, out DateTime time, out Int32 workerId, out Int32 sequence)`
½âÎöÑ©»¨ Id£¬µÃµ½Ê±¼ä¡¢`WorkerId`¡¢ÐòÁкš£
˵Ã÷£º
- ½âÎöµÃµ½µÄ `time` ÊÇ `StartTimestamp` ËùÊôÊ±ÇøµÄʱ¼ä¡£
### 4.7 `DateTime ConvertKind(DateTime time)`
°ÑÊäÈëʱ¼äת»»ÎªÓë `StartTimestamp` ÏàͬµÄÊ±Çø£¬±ãÓÚÏà¼õ¡£
¹æÔò£º
- `time.Kind == DateTimeKind.Unspecified`£ºÖ±½Ó·µ»Ø£¨²»×öת»»£©
- `StartTimestamp.Kind == Utc`£º·µ»Ø `time.ToUniversalTime()`
- `StartTimestamp.Kind == Local`£º·µ»Ø `time.ToLocalTime()`
---
## 5. ¼¯ÈºÄ£Ê½£ºÈ·±£ WorkerId ¾ø¶ÔΨһ
### 5.1 `static ICache? Cluster`
`Snowflake.Cluster` ÓÃÓÚÅäÖÃÒ»¸ö»º´æÊµÀý×÷Ϊ WorkerId ·ÖÅäÆ÷£¬½¨ÒéʹÓà Redis¡£
- µ± `Cluster != null` ÇÒʵÀý `WorkerId` δÏÔʽÉèÖÃʱ£¬³õʼ»¯½×¶Î»áµ÷Óà `JoinCluster(Cluster)`¡£
### 5.2 `void JoinCluster(ICache cache, String key = "SnowflakeWorkerId")`
ͨ¹ý×ÔÔö¼ü´Ó¼¯Èº»ñÈ¡ WorkerId£º
- `workerId = (Int32)cache.Increment(key, 1)`
- `WorkerId = workerId & 1023`
ʹÓý¨Ò飺
- ÔÚ¶à½ø³Ì/¶à½Úµã³¡¾°£¬ÎÞÄÔÓÅÏȲÉÓü¯Èº·ÖÅä WorkerId¡£
- Ðè񻂿·Ö»·¾³£¨dev/test/prod£©Ê±£¬½¨ÒéΪ²»Í¬»·¾³Ê¹Óò»Í¬µÄ `key`£¬±ÜÃâ WorkerId ·ÖÅä½»²æ¡£
---
## 6. ÕýȷʹÓÃ×ËÊÆ
### 6.1 ÔÚÓ¦ÓÃÄÚ±£³Öµ¥Àý
¹Ø¼üµã£º
- ÿ¸öÓ¦ÓÃ/·þÎñÄÚ£¬¾¡Á¿Ö»´´½¨Ò»¸öÈ«¾Ö `Snowflake` ʵÀý¡£
- ÈôʹÓà ORM/Öмä¼þ£¨ÀýÈç XCode£©£¬ÐèÈ·±£Í¬Ò»ÕÅ±í£¨»òͬһҵÎñÓò£©²»Òª¸÷×Ô new Ò»¸ö `Snowflake`¡£
ʾÀý£º
```csharp
using NewLife.Data;
public static class IdGenerator
{
public static readonly Snowflake Instance = new()
{
// ÈçÓÐÐèÒª£¬ÔÚÊ״ε÷Óà NewId ǰÉèÖÃ
// StartTimestamp = new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Local),
// WorkerId = 1,
};
}
var id = IdGenerator.Instance.NewId();
```
### 6.2 ÏÔʽָ¶¨ WorkerId£¨ÍƼö£©
```csharp
var snow = new Snowflake { WorkerId = 1 };
var id = snow.NewId();
```
### 6.3 ʹÓü¯Èº·ÖÅä WorkerId£¨ÍƼö£¬·Ö²¼Ê½³¡¾°£©
```csharp
using NewLife.Caching;
using NewLife.Data;
Snowflake.Cluster = /* RedisCache ʵÀý */;
var snow = new Snowflake();
var id = snow.NewId();
```
---
## 7. ³£¼ûÎÊÌâÓë¿Ó
### 7.1 Ϊʲôǿµ÷¡°µ¥Àý¡±£¿
`Snowflake` Ö»±£Ö¤¡°±¾ÊµÀý¡±Éú³ÉµÄ Id Ψһ¡£
- Ö»Òª³öÏÖ¶à¸öʵÀý£¬²¢ÇÒ `WorkerId` Ò»Ñù£¬²¢·¢Ï¾ͿÉÄܲúÉúÖØ¸´¡£
### 7.2 ĬÈÏ WorkerId ÊÇ·ñ¿É¿¿£¿
ĬÈϲßÂÔʹÓà IP ÅÉÉúʵÀý Id + ½ø³Ì/Ïß³ÌÐÅÏ¢£¬Ä¿µÄÊǽµµÍͬ»ú³åÍ»¸ÅÂÊ£¬µ«ÎÞ·¨ÔÚËùÓл·¾³Ï¾ø¶ÔΨһ¡£
- ÈÝÆ÷»·¾³¡¢NAT¡¢Í¬Ò»¾ÖÓòÍø IP ±ä»¯¡¢½ø³ÌÖØÆôµÈ¶¼¿ÉÄÜÒýÈë³åÍ»¡£
- ¸ßÒªÇ󳡾°Ç¿ÁÒ½¨Ò飺ÏÔʽ WorkerId »òʹÓà Redis ×ÔÔö·ÖÅä¡£
### 7.3 ʱ¼ä»Ø²¦»á·¢Éúʲô£¿
- С·¶Î§»Ø²¦£º»áÑØÓÃÉÏ´Îʱ¼ä´Á¼ÌÐøÉú³É£¬±£³Öµ¥ÊµÀý²»Öظ´¡£
- »Ø²¦¹ý´ó£ºÅ׳öÒì³£¾Ü¾øÉú³É£¨·ÀÖ¹´ó¸ÅÂÊÅöײ£©¡£
### 7.4 ʹÓà `NewId(DateTime time)` ÊÇ·ñÒ»¶¨Î¨Ò»£¿
²»Ò»¶¨¡£
- ÔÚͬһºÁÃëÄÚ£¬ÐòÁкÅÖ»ÓÐ 12 루4096£©£¬³¬³ö»áȡģµ¼ÖÂÖØ¸´·çÏÕ¡£
- ÕâÀà API ¸üÊʺϡ°°´Ê±¼äÂä¿â/·ÖÇø¡±µÄÒµÎñÐèÇ󣬶ø²»ÊǸ߲¢·¢Ð´Èëͬһ¸öÒµÎñʱ¼äµã¡£
---
## 8. ¼æÈÝÐÔ˵Ã÷
- `Snowflake` ÊôÓÚ»ù´¡¿â£¬ÃæÏò `net45` ~ `net10` ¶àÄ¿±ê¿ò¼Ü¡£
- Ëã·¨ºËÐÄ»ùÓÚ `DateTime`¡¢`Interlocked`¡¢`Volatile`¡¢`ICache` µÈͨÓà API¡£
---
## 9. Ïà¹ØÁ´½Ó
- ÔÚÏßÎĵµ£º`https://newlifex.com/core/snow_flake`
- Ô´Â룺`NewLife.Core/Data/Snowflake.cs`
- µ¥Ôª²âÊÔ£º`XUnitTest.Core/Data/SnowflakeTests.cs`
|