Hi / Lo 알고리즘은 무엇입니까?
나는이 발견 한 자 NHibernate (이, 고유 키를 생성하는 섹션 5.1.4.2 하나의 방법이다) 문서,하지만 난 그것을 작동하는 방법의 좋은 설명을 발견하지 않았습니다.
나는 Nhibernate가 그것을 처리한다는 것을 알고 있으며 내부를 알 필요는 없지만 단지 궁금합니다.
Hi / Lo 알고리즘은 무엇입니까?
나는이 발견 한 자 NHibernate (이, 고유 키를 생성하는 섹션 5.1.4.2 하나의 방법이다) 문서,하지만 난 그것을 작동하는 방법의 좋은 설명을 발견하지 않았습니다.
나는 Nhibernate가 그것을 처리한다는 것을 알고 있으며 내부를 알 필요는 없지만 단지 궁금합니다.
답변:
기본 아이디어는 기본 키를 구성 할 두 개의 숫자 ( "높은"숫자 및 "낮은"숫자)가 있다는 것입니다. 클라이언트는 기본적으로 "높은"시퀀스를 증가시킬 수 있으며 다양한 "낮은"값으로 이전 "높은"값의 전체 범위에서 키를 안전하게 생성 할 수 있다는 것을 알고 있습니다.
예를 들어, 현재 값이 35 인 "높은"시퀀스가 있고 "낮은"숫자가 0-1023 범위에 있다고 가정합니다. 그런 다음 클라이언트는 시퀀스를 36으로 늘리고 (35를 사용하는 동안 다른 클라이언트가 키를 생성 할 수 있도록) 키 35/0, 35/1, 35/2, 35/3 ... 35/1023이 모두 가능합니다.
기본 키가없는 값을 삽입 한 다음 클라이언트로 다시 가져 오는 대신 클라이언트 측에서 기본 키를 설정할 수 있으면 매우 유용 할 수 있습니다 (특히 ORM의 경우). 이외에도 다른 어떤에서, 당신이 쉽게 상위 / 하위 관계를 확인하고 당신이 전에 모든 장소에 키를 가질 수 있습니다 의미 있는 그들에게 간단한 일괄 처리하게 삽입.
Jon의 답변 외에도
연결이 끊어진 상태에서 작업 할 수 있습니다. 그런 다음 클라이언트는 서버에 hi 숫자를 요청하고 lo 자체를 증가시키는 오브젝트를 작성할 수 있습니다. Lo 범위를 모두 사용할 때까지 서버에 접속할 필요가 없습니다.
이것은 매우 일반적인 질문 이므로이 답변을 기반으로하는이 기사를 작성 했습니다.
hi / lo 알고리즘은 시퀀스 도메인을 "hi"그룹으로 분할합니다. "hi"값은 동 기적으로 할당됩니다. 모든 "hi"그룹에는 최대 수의 "lo"항목이 제공되는데, 이는 동시 중복 항목에 대한 걱정없이 오프라인으로 할당 할 수 있습니다.
식별자 범위는 다음 공식으로 제공됩니다.
[(hi -1) * incrementSize) + 1, (hi * incrementSize) + 1)
"lo"값의 범위는 다음과 같습니다.
[0, incrementSize)
시작 값에서 적용되는 :
[(hi -1) * incrementSize) + 1)
모든 "lo"값이 사용되면 새로운 "hi"값이 페치되고 사이클이 계속됩니다.
이 기사 에서 더 자세한 설명을 찾을 수 있습니다 .
그리고이 시각적 인 프리젠 테이션도 쉽게 수행 할 수 있습니다.
hi / lo 옵티마이 저는 식별자 생성을 최적화하는 데는 좋지만 식별자 전략에 대해 전혀 알지 못하면 데이터베이스에 행을 삽입하는 다른 시스템에서는 잘 작동하지 않습니다.
이벤트에게 최대 절전 모드 풀링-LO를 옵티 마이저를 제공하며, 하이 /로 제너레이터 전략의 장점을 제공하는 동시에이 시퀀스 할당 전략을 인식하지 못하는 다른 타사 클라이언트와의 상호 운용성을 제공합니다.
효율적이고 다른 시스템과 상호 운용이 가능하므로 풀 최적화 알고리즘은 레거시 hi / lo 식별자 전략보다 훨씬 더 나은 후보입니다.
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "name") @SequenceGenerator(name="name", sequenceName = "name_seq", allocationSize=100)
ID를 사용 하고 있습니다.
, (hi * incrementSize) + 1)
... , hi * incrementSize)
맞습니까?
Lo는 캐시 된 할당 자로서, 키 공간을 사람이 현명하게 선택할 수있는 의미있는 크기의 범위 (예 : 한 번에 200 개의 키를 얻는 것)가 아닌 일부 기계 단어 크기에 따라 큰 청크로 나눕니다.
Hi-Lo 사용은 서버를 다시 시작할 때 많은 수의 키를 낭비하고 사람에게 친숙하지 않은 키 값을 생성하는 경향이 있습니다.
Hi-Lo 할당 기보다 "Linear Chunk"할당 기가 더 좋습니다. 이것은 비슷한 테이블 기반 원칙을 사용하지만 작고 편리한 크기의 청크를 할당하고 사람에게 친숙한 가치를 창출합니다.
create table KEY_ALLOC (
SEQ varchar(32) not null,
NEXT bigint not null,
primary key (SEQ)
);
다음을 할당하려면 200 키 (서버에서 범위로 유지되고 필요에 따라 사용됨) :
select NEXT from KEY_ALLOC where SEQ=?;
update KEY_ALLOC set NEXT=(old value+200) where SEQ=? and NEXT=(old value);
이 트랜잭션을 커밋 할 수있는 경우 (다시 시도를 사용하여 경합 처리) 200 개의 키를 할당하고 필요에 따라 분배 할 수 있습니다.
청크 크기가 20에 불과한이 체계는 Oracle 시퀀스에서 할당하는 것보다 10 배 빠르며 모든 데이터베이스간에 100 % 이식 가능합니다. 할당 성능은 안녕과 같습니다.
Ambler의 아이디어와 달리 키 스페이스를 연속 선형 번호 선으로 취급합니다.
이렇게하면 복합 키에 대한 자극을 피할 수 있으며 (실제로는 좋은 아이디어는 아님) 서버를 다시 시작할 때 전체 단어를 낭비하지 않아도됩니다. "친숙한"인간 규모 키 값을 생성합니다.
Mr Ambler의 아이디어는 이와 비교하여 16 비트 또는 32 비트의 높은 비트를 할당하고 하이 워드가 증가함에 따라 큰 인간 친화적이지 않은 키 값을 생성합니다.
할당 된 키 비교 :
Linear_Chunk Hi_Lo
100 65536
101 65537
102 65538
.. server restart
120 131072
121 131073
122 131073
.. server restart
140 196608
디자인 측면에서, 그의 솔루션은 Linear_Chunk보다 기본적으로 여러 줄 (복합 키, 대형 단어 제품)에서 더 복잡하지만 비교 이점은 없습니다.
Hi-Lo 디자인은 OO 매핑 및 지속성 초기에 일어났습니다. 요즘에는 최대 절전 모드와 같은 지속성 프레임 워크가 기본적으로 더 간단하고 더 나은 할당자를 제공합니다.
Hi / Lo 알고리즘이 내 경험에 기반한 복제 시나리오를 가진 여러 데이터베이스에 완벽하다는 것을 알았습니다. 이것을 상상해보십시오. 뉴욕 (별칭 01)에 서버가 있고 로스 앤젤레스 (별칭 02)에 다른 서버가있는 경우 PERSON 테이블이 있습니다 ... 그래서 사람이 생성 될 때 뉴욕에서는 항상 01을 HI 값으로 사용합니다 LO 값은 다음 보안입니다. 포 예제.
로스 앤젤레스에서는 항상 HI 02를 사용합니다. 예를 들면 다음과 같습니다.
따라서 데이터베이스 복제 (어떤 브랜드에 상관없이)를 사용하면 기본 키와 충돌 등이 걱정되지 않고 모든 기본 키와 데이터가 쉽고 자연스럽게 결합됩니다.
이 시나리오에서 가장 좋은 방법입니다.