I am in the progress of migrating a database from Microsoft SQL Server to MySQL/MariaDB. On MSSQL, the database uses the uniqueidentifier
(GUID) datatype for all primary keys. NHibernate is used to map data between database and application, and the guid.comb
strategy is employed for GUID generation to avoid fragmentation of the clustered indexes.
MySQL not having a dedicated GUID data type, the new database schema uses BINARY(16)
for all identifiers. Without making any changes to the NHibernate mappings, I can start our application, persist new entities and load them back up from the MySQL database. Great! However, it turns out that the sequantially generated GUIDs are ordered very much non-sequantially in the BINARY(16)
column, yielding unacceptable index fragmentation.
Reading up on the issue, it turns out that MSSQL has a quite special method for sorting GUIDs. The 16 bytes are ordered first by the last six bytes, then by the precending in reversed groups, whereas my naïve MySQL implementation sorts on the first byte first, then the next and so forward.
And this leads to my question: How to avoid this fragmentation in the MySQL database, while keeping the existing GUIDs and the guid.comb
strategy? I have an idea for a solution myself (posted below) but I cannot help feeling I might have missed something. Surely, others must have dealt with this issue before, and maybe there is a simple way to get around it.