Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Làm thế nào để tránh phân mảnh khi sử dụng khóa chính NHibernate Guid.comb trong MySQL?

Như được quan sát bởi Alberto Ferrari được thảo luận tại đây trên StackOverflow , Microsoft SQL Server sắp xếp các GUID bằng cách so sánh các byte theo một thứ tự cụ thể. Vì MySQL sẽ sắp xếp một BINARY(16) "thẳng tiến", tất cả những gì chúng ta cần làm, là sắp xếp lại thứ tự các byte khi đọc / ghi vào cơ sở dữ liệu.

NHibernate cho phép chúng tôi xác định các kiểu dữ liệu tùy chỉnh, có thể được sử dụng trong ánh xạ giữa cơ sở dữ liệu và các đối tượng. Tôi đã triển khai BinaryGuidType , có khả năng sắp xếp lại thứ tự các byte được tạo bởi Guid.ToByteArray() theo cách MSSQL sắp xếp các GUID và sắp xếp lại chúng theo định dạng được chấp nhận bởi Guid(byte[]) phương thức khởi tạo.

Thứ tự byte có dạng như sau:

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

Lưu System.Guid tới BINARY(16) như sau:

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

Đọc lại các byte vào System.Guid như sau:

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

Mã nguồn đầy đủ cho BinaryGuidType tại đây.

Điều này dường như hoạt động tốt. Tạo và duy trì 10.000 đối tượng mới trong một bảng, chúng được lưu trữ hoàn toàn tuần tự, không có dấu hiệu phân mảnh chỉ mục.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách tham gia hai bảng trong MySQL

  2. Sử dụng biến env trong Spring Boot's application.properties

  3. Backtrace từ truy vấn SQL đến mã ứng dụng?

  4. Làm cách nào để sử dụng hàng câu lệnh SELECT IF trong mySQL để THAM GIA một bảng khác?

  5. PDO ::PARAM cho ngày tháng?