데이터베이스의 기본 키로 UUID를 사용하는 장단점에 대해 읽었습니다.기본 키로 사용하는 사용자 지정 UUID
필자가 들었던 주요 논점은 순차적으로 생성되지 않으면 색인을 조각 내고 페이징 문제를 일으킬 수 있다는 것입니다 (데이터베이스의 크기가 폭발적이라고 들었지만 지금은 옆으로 두십시오).
MSSQL Server를 사용하면 (사용자 정의 메소드를 사용하여 데이터베이스 내에서 순차적 UUID를 생성 할 수 있습니다 예를 들어 표 MyUniqueTable를 CREATE (UniqueColumn 고유 식별자의 DEFAULT NEWSEQUENTIALID()).
문제를이 비록 비 표준을 준수 생성한다는 것입니다 함께 UUID 분명히 순차적 밤은 그 내가 뒤로 형식을 설계 및 사용에 대한 빌더 클래스에 캡슐화 또는 연구 있습니다.
/**
* <p>
* Reverse engineering effort to replicate how SQL Server creates ordered
* UUIDs so that we may construct them within the application. The builder will
* only accept version 1 and version 14 (Microsoft specific) uuid objects as a
* seed.
* </p>
* <p>
* The algorithm is reversible so that a version 1 uuid may be created from a version
* 14 uuid and vice versa.
* </p>
* @author Michael Lambert
*
*/
public static class MsSqlOrderedUuidBuilder {
private static final TimeBasedGenerator generator = Generators.timeBasedGenerator();
private final UUID uuid;
public MsSqlOrderedUuidBuilder(UUID uuid) {
if(uuid.version() != 1 && uuid.version() != 14) {
throw new IllegalArgumentException(String.format("UUID is not a version 1 UUID (version is %d)", uuid.version()));
}
this.uuid = uuid;
}
public MsSqlOrderedUuidBuilder() {
this(generator.generate());
}
private long getMostSignificantBits() {
ByteBuffer buffer = ByteBuffer.wrap(new byte[8]);
buffer.putLong(uuid.getMostSignificantBits());
buffer.rewind();
byte[] timeLow = new byte[4];
buffer.get(timeLow);
byte[] timeMid = new byte[2];
buffer.get(timeMid);
byte[] timeHigh = new byte[2]; // time_high and version
buffer.get(timeHigh);
buffer.clear();
buffer.order(buffer.order().equals(ByteOrder.LITTLE_ENDIAN) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
buffer.put(timeHigh);
buffer.put(timeMid);
buffer.put(timeLow);
return buffer.getLong(0);
}
private long getLeastSignificantBits() {
return uuid.getLeastSignificantBits();
}
public UUID build() {
return new UUID(getMostSignificantBits(), getLeastSignificantBits());
}
}
을 내가 다른 데이터베이스에서 생성 된 UUID를 저장하기 위해이 클래스를 사용하려고하면 (내가 또한 MySQL에 쓸 필요가있다) d와 나는 원래의 문제로 되돌아 간다.
/**
* <p>
* Creates a custom UUID type with sequential bytes. The builder must be seeded with a version 1 uuid and the
* algorithm is reversible.
* </p>
* @author Michael Lambert
*
*/
public static class SequentialUuidBuilder {
private static final TimeBasedGenerator generator = Generators.timeBasedGenerator();
private final UUID uuid;
public SequentialUuidBuilder(UUID uuid) {
if(uuid.version() != 1 && uuid.version() != 13) {
throw new IllegalArgumentException(String.format("UUID is not a version 1 UUID (version is %d)", uuid.version()));
}
this.uuid = uuid;
}
public SequentialUuidBuilder() {
this(generator.generate());
}
private long getVersion13MostSignificantBits() {
if(uuid.version() == 1) {
// System.out.println(String.format("original: %x", version1.getMostSignificantBits()));
//
// System.out.println(String.format("lowa %x", timeLowA));
//
// 0xAAAAA00000000000L
// 0x0000000AAAAA0000L
//
long timeLowPartA = (uuid.getMostSignificantBits() & 0xFFFFF00000000000L) >>> 28;
//
// 0x00000BBB00000000L
// 0x0000000000000BBBL
//
long timeLowPartB = (uuid.getMostSignificantBits() & 0x00000FFF00000000L) >>> 32;
//
// System.out.println(String.format("lowb %x", timeLowB));
//
// 0x00000000MMMM0000L
// 0x000MMMM000000000L
//
long timeMid = (uuid.getMostSignificantBits() & 0x00000000FFFF0000L) << 20;
//
// System.out.println(String.format("med %x", (timeMid)));
//
// 0x0000000000000HHHL
// 0xHHH0000000000000L
//
long timeHigh = (uuid.getMostSignificantBits() & 0x0000000000000FFFL) << 52;
//
// System.out.println(String.format("high %x", timeHigh));
//
// 0x000000000000V000L
// 0x000000000000V000L
//
// long version = (version1.getMostSignificantBits() & 0x000000000000F000L);
//
// System.out.println(String.format("version %x", version));
//
// 0x0000000AAAAA0000L
// 0x0000000000000BBBL
// 0x000MMMM000000000L
// 0xHHH0000000000000L
// 0x000000000000V000L <-- we don't change where the version is stored because we want to respect that part of the spec
// ____________________
// 0xHHHMMMMAAAAAVBBBL
//
long ordered = timeLowPartA | timeLowPartB | timeMid | timeHigh | 0x000000000000D000L; // custom version
return ordered;
}
return 0;
}
public long getVersion1MostSignificantBits() {
//
// 0xHHHMMMMAAAAAVBBBL
//
long timeLowPartA = (uuid.getMostSignificantBits() & 0x0000000FFFFF0000L) << 28;
long timeLowPartB = (uuid.getMostSignificantBits() & 0x0000000000000FFFL) << 32;
long timeMid = (uuid.getMostSignificantBits() & 0x000FFFF000000000L) >> 20;
long timeHigh = (uuid.getMostSignificantBits() & 0xFFF0000000000000L) >> 52;
//
// 0xAAAAA00000000000L
// 0x00000000MMMM0000L
// 0x00000BBB00000000L
// 0x0000000000000HHHL
// 0x000000000000V000L
// ___________________
// 0xAAAAABBBMMMMVHHHL
//
long bits = timeLowPartA | timeLowPartB | timeMid | timeHigh | 0x0000000000001000L; // reinstate version
return bits;
}
private long getMostSignificantBits() {
return (uuid.version() == 13) ? getVersion1MostSignificantBits() : getVersion13MostSignificantBits();
}
private long getLeastSignificantBits() {
return uuid.getLeastSignificantBits();
}
public UUID build() {
return new UUID(uuid.version() == 13 ? getVersion1MostSignificantBits() : getMostSignificantBits(), getLeastSignificantBits());
}
}
질문이다 :이 허용 연습
내 용액 바이트 배열로 직렬화 될 때 순차적으로 정렬되는 것을 내 가역 맞춤 UUID를 작성했다? BINARY (16)를 사용하여 기본 키를 저장할 수 있으며이 방식으로 맞춤 식별자를 사용할 수 있습니까?
감사합니다. Vive la Stackoverflow!
데이터베이스 서버의 분산 클러스터에서 고유해야합니다. 또한 순차적 인 id와 날짜를 가진 복합 키를 요소로 사용할 가능성을 연구했지만 UUID를 사용하는 것이 더 분명한 선택 인 것 같습니다 (유일한 목적은 배포에 관계없이 엔티티를 고유하게 식별하는 것임). – MacFlecknoe
http://www.digitilapia.com/custom_uuid_as_primary_key – MacFlecknoe