Als waargenomen door Alberto Ferrari
en hier besproken op StackOverflow
, sorteert Microsoft SQL Server GUID's door de bytes in een specifieke volgorde te vergelijken. Omdat MySQL een BINARY(16)
. zal sorteren "straight-forward", alles wat we hoeven te doen, is de bytes opnieuw te ordenen bij het lezen/schrijven naar de database.
Met NHibernate kunnen we aangepaste gegevenstypen definiëren, die kunnen worden gebruikt in toewijzingen tussen database en objecten. Ik heb een BinaryGuidType
. geïmplementeerd , in staat om de bytes opnieuw te ordenen die zijn geproduceerd door Guid.ToByteArray()
volgens de manier waarop MSSQL GUID's sorteert en ze opnieuw ordent in het formaat dat wordt geaccepteerd door de Guid(byte[])
constructeur.
De bytevolgorde ziet er als volgt uit:
int[] ByteOrder = new[] { 10,11,12,13,14,15,8,9,6,7,4,5,0,1,2,3 };
Een System.Guid
opslaan naar een BINARY(16)
gaat als volgt:
var bytes = ((Guid) value).ToByteArray();
var reorderedBytes = new byte[16];
for (var i = 0; i < 16; i++)
{
reorderedBytes[i] = bytes[ByteOrder[i]];
}
NHibernateUtil.Binary.NullSafeSet(cmd, reorderedBytes, index);
De bytes teruglezen in een System.Guid
gaat als volgt:
var bytes = (byte[]) NHibernateUtil.Binary.NullSafeGet(rs, names[0]);
if (bytes == null || bytes.Length == 0) return null;
var reorderedBytes = new byte[16];
for (var i = 0 ; i < 16; i++)
{
reorderedBytes[ByteOrder[i]] = bytes[i];
}
Volledige broncode voor het BinaryGuidType
hier.
Dit lijkt goed te werken. Door 10.000 nieuwe objecten in een tabel te maken en te bewaren, worden ze volledig opeenvolgend opgeslagen, zonder tekenen van indexfragmentatie.