2013-09-07 2 views
0

우리는 새로운 사람을 데이터베이스에 추가 할 때 고유 번호를 할당해야한다는 요구 사항이 있습니다. 이 번호는 시스템이 가동 될 때 정의 된 번호부터 시작합니다. 따라서 클라이언트가 "Start at 500,000!"이라고 말하면 할당 된 첫 번째 ID는 500000입니다.DB로 숫자 증가 처리하기

쉬운 자동 증가 악마입니다.

그러나이 IDAccount Number이며 외부 고객에게 전송되어 해당 계정을 계정에 연결합니다. 아이디어는 자동 inc 기본 키를 사용했을 수도 있지만 PK를 외부 '개인 번호'로 사용하는 것이 좋지 않다고 생각합니다.

누군가가 우리가 그 번호를 추가 할 사람 테이블에 auto inc pk와 id가있는 테이블을 가지고 있다고 언급했습니다. 그러나 그것은 이상하게 보입니다.

제 생각에는 실제로 행이 하나 뿐인 시스템의 시스템 설정이 포함 된 settings 테이블에 새 열을 추가하는 것이 좋습니다. 열은 INT이고 NextAvailableId이라고 할 수 있습니다. 행의 모든 ​​열은 (RowVersion) 인 Version 열입니다.

내 계획은 단순히 다음을 수행 할 GetNextId 또는 무엇인가라는 함수를 만드는 것입니다 :

  1. 라는 변수를 만듭니다 @AssignedID
  2. 로부터의 NextAvailableId를 가져옵니다 @Version
  3. 라는 변수를 만듭니다 설정 테이블뿐만 아니라 버전. NextAvailableId = AssignedID + 1 WHERE version = @Version
  4. 설정 설정 테이블
  5. Set AssignedID = NextAvailableId
  6. 업데이트, 업데이트 된 행 수를 확인합니다. 1 일 경우 다른 프로세스가 ID를 받기 전에 최신 ID를 가져 와서 증분하여 다시 테이블에 저장합니다.
  7. 업데이트 된 행 수가 0 인 경우 - 누군가가 우리 앞에 번호를 부여 했으므로 업데이트 된 행이있을 때까지 다시 시도하십시오.

내 개인에게 '계좌 번호'를 지정하는 것이 안전하고 유효한 계획 인 것 같습니까?

사실 그 사람이나 계정 코드는 없습니다. 별도의 시스템에 저장하기 위해 사람에게 적용해야하는 공급 업체 ID입니다. Person과 Account를 (가난한) 예제로 사용하십시오.

내가해야 할 일은 '계정 번호'의 고유 한 할당을 처리하는 방법을 찾는 것입니다. 수동 방식이 좋지 않은 아이디어이고 더 좋은 방법이 있다면 - 그 것이 많은 도움이 될 것입니다.

+3

당신이 당신의 자신의 * 매뉴얼 * 증가 방식을 사용하도록 선택하는 경우, 당신이해야합니다 ** 확신 ** 당신의 증가 기능도 부하가 ** 동시성 안전 **입니다. 그리고 ** 성취하기가 쉽지 않습니다 **! –

+0

감사합니다. @marc_s. 그래, 그게 내가하려는거야. 따라서 행 버전을 사용하여 사용 가능한 ID를 확보하는 것이 나에게 꽤 안전 해 보입니다. 하지만 뭔가를 놓친 것일까 요? 잠그고있어? – Craig

+0

[이 다른 질문을 참조하고 Remus Rusanu의 대답] (http://stackoverflow.com/questions/5083846/sql-server-2005-using-generated-sequences-instead-of-identity-columns) 방법 ** 안전하게 ** –

답변

2

마지막 ID를 수동으로 늘리는 방법에 동의하지 않지만 marc_s에 동의합니다. 동시성에주의해야합니다.

가장 빠른 방법은 함수 내에서 READ UNCOMMITTED의 트랜잭션을 분리 수준으로 결합하고 작은 Mutex 필드를 결합하는 것입니다.여기에 의사 코드는 다음과 같습니다

  1. 시작과 함께 새로운 트랜잭션 READ, 미완료
  2. 확인이 뮤텍스 플래그 = 0 (다른 방법을 실행)
  3. 플래그 = 1, 루프
  4. 만약의 경우 플래그 = 0, 1
  5. 로 설정하면 다시 테이블에
  6. 설정 마지막으로 ID를 원하는대로 마지막 ID를
  7. 증가를 가져
  8. 세트 M 다시 0
  9. 반환 새로운 ID로 utex 플래그는/

READ UNCOMMITED 여러 실행은 다른 트랜잭션이 계속 실행하고 아직 커밋되지 않은 상태에서 뮤텍스 플래그의 값을 확인할 수 있습니다 트랜잭션을 커밋합니다.

편집 :

나는 당신이 당신의 PK 대신 사용하는 기본값으로 새 열을 추가하는 것이 좋습니다. 다음과 같은 예 :

CREATE FUNCTION dbo.GetLastId() 
RETURNS INT 
AS 
    BEGIN 
     RETURN SELECT MAX(AccountID) + 1 FROM dbo.tblUsers 
    END 

-- Set the default value to the column 
ALTER TABLE dbo.tblUsers 
ADD AccountID SET DEFAULT (dbo.GetLastId()) 
+1

질문자가 안전한 접근 방법인지 묻습니다. 병행 성은 그의 아이디어의 나쁜면이다. –

+1

아마 당신의 대답에 나쁜 생각이 들기도한다. – dcaswell

+0

감사합니다 - "나는 마지막 ID를 수동으로 늘리는 접근 방식에 동의하지 않지만". 내가 생각할 수있는 유일한 다른 점은 자동 증가 기능을 사용하는 것입니다. 그러나 어떤 이유로이 방법이 올바른 방법이 아닌지 걱정됩니다. – Craig