解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
大石头 authored at 2018-05-15 21:21:05
6.72 KiB
X
# 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`