문제

우리는 일반적으로 OLTP인 애플리케이션을 설계하기 위해 노력하고 있습니다(예:구매 시스템).그러나 특히 이 사용자는 일부 사용자가 오프라인 상태여야 하므로 DB를 자신의 컴퓨터에 다운로드하여 작업한 다음 LAN에 연결되면 다시 동기화할 수 있어야 합니다.

나는 이것이 이전에 수행되었다는 것을 알고 있지만 이 특정 모델에 대한 경험이 없다는 점에 주목하고 싶습니다.

제가 생각한 아이디어 중 하나는 GUID를 테이블 키로 사용하는 것이었습니다.예를 들어 구매 주문에는 숫자(자동 숫자)가 아니라 대신 GUID가 있으므로 모든 오프라인 클라이언트가 이를 생성할 수 있고 DB에 다시 연결할 때 충돌이 발생하지 않습니다.

어떤 이유로 이것이 나쁜 생각입니까?GUID 키를 통해 이러한 테이블에 액세스하는 속도가 느립니까?

이러한 유형의 시스템에 대한 경험이 있습니까?이 문제를 어떻게 해결하셨나요?

감사해요!
다니엘

도움이 되었습니까?

해결책

Guids를 기본 키로 사용하는 것은 허용되며 고려하는 것과 동일한 이유로 상당히 표준적인 관행으로 간주됩니다.과도하게 사용되면 디버깅 및 관리가 다소 지루해질 수 있으므로 가능하면 코드 테이블 및 기타 참조 데이터에서 제외시키십시오.

당신이 걱정해야 할 것은 사람이 읽을 수 있는 식별자입니다.가이드는 다른 사람과 교환할 수 없습니다. 가이드인 경우 전화로 주문 번호를 확인하는 것을 상상할 수 있습니까?따라서 오프라인 시나리오에서는 여전히 생성해야 할 수도 있습니다. 무엇 - 게시자(워크스테이션/사용자) ID 및 일부 시퀀스 번호와 같으므로 주문 번호는 123-5678일 수 있습니다. -.

그러나 이는 일련 번호 보유에 대한 비즈니스 요구 사항을 충족하지 못할 수 있습니다.실제로 규제 요구 사항은 영향을 미칠 수 있습니다. 일부 규정(SOX일 수도 있음)에서는 송장 번호가 순차적이어야 합니다.이러한 경우 나중에 시스템이 동기화될 때 수정되는 일종의 형식 번호를 생성해야 할 수도 있습니다.OrderId(Guid), OrderNo(int), ProformaOrderNo(varchar)가 있는 테이블이 나타날 수 있습니다. 약간의 복잡성이 발생할 수 있습니다.

최소한 guid를 기본 키로 사용한다는 것은 결국 동기화가 발생할 때 계단식 업데이트를 많이 수행할 필요가 없다는 것을 의미합니다. 사람이 읽을 수 있는 숫자만 업데이트하면 됩니다.

다른 팁

@SqlMenace

GUID에는 다른 문제가 있습니다. GUID는 순차적이지 않으므로 삽입이 여기저기로 분산되어 페이지 분할 및 인덱스 조각화가 발생합니다.

사실이 아니다. 기본 키 != 클러스터형 인덱스.

클러스터형 인덱스가 다른 열인 경우("inserted_on"이 떠오름) 삽입은 순차적이며 페이지 분할이나 과도한 조각화가 발생하지 않습니다.

이는 GUID를 완벽하게 활용하는 것입니다.유일한 단점은 INT에 대한 GUID 작업 시 약간의 복잡성과 약간의 크기 차이(16바이트 대 4바이트)입니다.

나는 둘 다 큰 문제가 아니라고 생각합니다.

Guid 키를 통해이 테이블에 액세스 할 수 있습니까?

GUID에는 다른 문제가 있습니다. GUID는 순차적이지 않으므로 삽입이 여기저기로 분산되어 페이지 분할 및 인덱스 조각화가 발생합니다.

SQL Server 2005 MS에서는 이 문제를 해결하기 위해 NEWSEQUENTIALID()를 도입했습니다. 유일한 문제는 NEWSEQUENTIALID를 테이블의 기본값으로만 사용할 수 있다는 것입니다.

이것이 오래된 문제라는 것이 맞습니다. 두 가지 표준 솔루션이 있습니다.

  • 고유 식별자를 기본 키로 사용합니다.가독성이 염려되는 경우 GUID를 사용하는 대신 고유한 식별자를 롤링할 수 있습니다.고유 식별자는 날짜 및 기계에 대한 정보를 사용하여 고유한 값을 생성합니다.

  • '배우' + 식별자의 복합 키를 사용합니다.모든 사용자는 숫자로 된 행위자 ID를 가지며, 새로 삽입된 행의 키는 행위자 ID와 다음으로 사용 가능한 식별자를 사용합니다.따라서 두 행위자 모두 ID가 "100"인 새 행을 삽입하면 기본 키 제약 조건을 위반하지 않습니다.

개인적으로 저는 복합 키가 외래 키만큼 지루하다고 생각하기 때문에 첫 번째 접근 방식을 선호합니다.인간의 가독성에 대한 불만은 과장되었다고 생각합니다. 어쨌든 최종 사용자는 키에 대해 아무것도 알 필요가 없어야 합니다!

guid.comb를 활용하세요 - 색인 생성 작업을 관리합니다.그 이후에 성능 문제를 다루고 있다면 곧 확장 전문가가 될 것입니다.

GUID를 사용하는 또 다른 이유는 데이터베이스 리팩토링을 활성화하는 것입니다.Customers 엔터티에 다형성이나 상속 등을 적용하기로 결정했다고 가정해 보겠습니다.이제 고객과 직원이 Person에서 파생되어 테이블을 공유하도록 하려고 합니다.고유한 식별자가 있으면 데이터 마이그레이션이 간단해집니다.싸울 시퀀스나 정수 ID 필드가 없습니다.

나는 단지 당신을 가리킬 것입니다 표준 Guid에 비해 Sequential Guid의 성능 향상은 무엇입니까?, GUID 대화를 다룹니다.

사람이 쉽게 읽을 수 있도록 컴퓨터 ID를 할당한 다음 가능하면 해당 컴퓨터의 일련 번호를 사용하는 것이 좋습니다.하지만 이를 위해서는 컴퓨터 ID 할당을 관리해야 합니다.하나 또는 두 개의 열로 수행할 수 있습니다.

하지만 저는 개인적으로 SGUID 답변을 좋아합니다.

Guids는 확실히 표준 정수 키보다 느리고 더 많은 메모리를 사용하지만 이것이 문제인지 여부는 시스템에 표시되는 로드 유형에 따라 달라집니다.백엔드 DB에 따라 guid 필드 인덱싱에 문제가 있을 수 있습니다.

guid를 사용하면 전체 문제가 단순화되지만 그에 대한 비용을 지불하면 성능과 디버그 가능성도 향상됩니다. 테스트 쿼리에 guid를 입력하면 정말 빨리 낡아지게 됩니다!

백엔드는 SQL Server 2005입니다.
프런트엔드/애플리케이션 로직은 .Net입니다.

GUID 외에도 오프라인 컴퓨터가 새 데이터를 중앙 데이터베이스에 다시 동기화할 때 발생하는 "병합"을 해결하는 다른 방법을 생각할 수 있습니까?
즉, 키가 INT인 경우 기본적으로 가져올 때 모든 항목의 번호를 다시 지정해야 합니다.GUID를 사용하면 그런 일이 발생하지 않을 것입니다.

GUID를 사용하면 두 개의 데이터베이스를 하나로 병합해야 할 때 많은 작업이 절약되었습니다.

데이터베이스가 노트북에 다운로드하여 오프라인으로 작업할 수 있을 만큼 작은 경우 int와 Guids 간의 성능 차이에 대해 너무 걱정할 필요가 없습니다.그러나 시스템을 개발하고 문제를 해결할 때 int가 얼마나 유용한지 과소평가하지 마십시오!Guids 사용 여부에 관계없이 상당히 복잡한 가져오기/동기화 논리를 생각해 내야 하므로 생각만큼 도움이 되지 않을 수 있습니다.

@사이먼,

당신은 아주 좋은 점수를 올렸습니다.나는 오프라인에서 생성하고 동기화 시 다시 생성할 "임시" "사람이 읽을 수 있는" 숫자에 대해 이미 생각하고 있었습니다.하지만 나는 외래 키 등을 사용하는 것을 피하고 싶었습니다.

나는 이것을 위해 SQL Server Compact Edition을 살펴보기 시작할 것입니다!모든 문제에 도움이 됩니다.

SQL Server 2005 Compact Edition의 데이터 저장소 아키텍처

그것은 특별히 설계되었습니다

현장 강제 적용(FFA).FFA는 일반적으로 다음 속성 중 하나 이상을 공유합니다.

이를 통해 사용자는 백엔드 네트워크 (클라이언트 위치, 도로, 공항 또는 집)에서 연결이 끊어지면서 작업 기능을 수행 할 수 있습니다.

FFA는 일반적으로 가끔 연결을 위해 설계되었으므로 사용자가 클라이언트 애플리케이션을 실행할 때 어떤 종류의 네트워크 연결이 필요하지 않음을 의미합니다.FFA에는 종종 연결된 모드 및 연결 해제 된 모드 모두에서 백엔드 데이터베이스의 데이터에 동시에 액세스하고 사용할 수있는 여러 클라이언트가 포함됩니다.

FFA는 오프라인 지원을 위해 백엔드 데이터베이스에서 클라이언트 데이터베이스로 데이터를 복제 할 수 있어야합니다.또한 응용 프로그램이 네트워크에 연결할 수있을 때 클라이언트에서 서버로 수정, 추가 또는 삭제 된 데이터 레코드를 복제 할 수 있어야합니다.

가장 먼저 떠오르는 생각:MS는 이와 같은 시나리오를 지원하기 위해 DataSet 및 DataAdapter 모델을 설계하지 않았습니까?

MS가 ADO 레코드 세트 모델을 현재 DataSet 모델로 변경하여 오프라인에서도 잘 작동한다는 내용을 읽었습니다.그리고 이것도 있어요 ADO.NET용 동기화 서비스

외래 키도 사용하는 DataSet 모델을 활용하는 코드를 본 적이 있는데 DataAdapter를 사용할 때 여전히 완벽하게 동기화됩니다.동기화 서비스를 사용해 보지는 않았지만 귀하도 그 혜택을 누릴 수 있을 것이라고 생각합니다.

도움이 되었기를 바랍니다.

@Portman 기본적으로 PK == 클러스터형 인덱스, 기본 키 제약 조건을 생성하면 클러스터형 인덱스가 자동으로 생성됩니다. 클러스터링을 원하지 않으면 비클러스터형을 지정해야 합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top