我正在将数据库从 Microsoft SQL Server 迁移到 MySQL/MariaDB。在 MSSQL 上,数据库uniqueidentifier
对所有主键使用 (GUID) 数据类型。NHibernate 用于在数据库和应用程序之间映射数据,并guid.comb
采用该策略生成 GUID,以避免聚集索引的碎片化。
MySQL 没有专用的 GUID 数据类型,新的数据库模式BINARY(16)
用于所有标识符。无需对 NHibernate 映射进行任何更改,我就可以启动我们的应用程序,持久保存新实体并从 MySQL 数据库加载它们。伟大的!然而,事实证明,按顺序生成的 GUID 在BINARY(16)
列中的排序非常不按顺序排列,从而产生不可接受的索引碎片。
阅读这个问题后,发现MSSQL 有一种非常特殊的 GUID 排序方法。这 16 个字节首先按最后 6 个字节排序,然后按倒序排列,而我的幼稚 MySQL 实现首先按第一个字节排序,然后是下一个字节,依此类推。
这引出了我的问题:如何避免 MySQL 数据库中的这种碎片,同时保留现有的 GUID 和guid.comb
策略?我自己有一个解决方案的想法(发布在下面),但我不禁觉得我可能错过了一些东西。当然,其他人之前一定已经处理过这个问题,也许有一种简单的方法可以解决这个问题。