sql >> Database teknologi >  >> RDS >> Mysql

Hvordan undgår man fragmentering, når man bruger NHibernate guid.comb primærnøgle i MySQL?

Som observeret af Alberto Ferrari og diskuteret her på StackOverflow , Microsoft SQL Server sorterer GUID'er ved at sammenligne bytes i en bestemt rækkefølge. Som MySQL vil sortere en BINARY(16) "straight-forward", alt hvad vi skal gøre, er at omorganisere bytes, når du læser/skriver til databasen.

NHibernate giver os mulighed for at definere brugerdefinerede datatyper, som kan bruges i kortlægninger mellem database og objekter. Jeg har implementeret en BinaryGuidType , der er i stand til at omarrangere bytes produceret af Guid.ToByteArray() i henhold til den måde, hvorpå MSSQL sorterer GUID'er og omorganiserer dem tilbage til det format, der accepteres af Guid(byte[]) konstruktør.

Byterækkefølgen ser sådan ud:

int[] ByteOrder = new[] { 10,11,12,13,14,15,8,9,6,7,4,5,0,1,2,3 };

Gemmer en System.Guid til en BINARY(16) går sådan her:

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);

Læsning af bytes tilbage i en System.Guid går sådan her:

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];
}

Fuld kildekode til BinaryGuidType her.

Dette ser ud til at fungere godt. Ved at skabe og vedholde 10.000 nye objekter i en tabel, gemmes de fuldstændig sekventielt uden tegn på indeksfragmentering.




  1. Eksport af en PostgreSQL-database med phpPgAdmin

  2. java.lang.NoSuchFieldError:NONE i dvale med Spring 3, maven, JPA, c3p0

  3. Konvertering af en datetime2-datatype til en datetime-datatype resulterer i en værdi uden for området

  4. Forskelle i proceduremæssige og objektorienterede implementeringer af mysql i php?