sqlserver 데이터베이스 메 인 키 생 성 방식 소결(sqlserver,my sql)
8383 단어 메 인 키
--
CREATE TABLE [Identity](
Id INT IDENTITY(1,2) NOT NULL PRIMARY KEY,-- 1, 2
Number VARCHAR(20) UNIQUE NOT NULL,
Name VARCHAR(20) NOT NULL,
Password VARCHAR(20) DEFAULT(123),
Description VARCHAR(40) NULL
)
--
INSERT INTO [Identity](Number,Name,Description) VALUES('001','1st','Id=1, 1')
INSERT INTO [Identity](Number,Name,Description) VALUES('002','2nd','Id=3, 1, 2')
INSERT INTO [Identity](Number,Name,Description) VALUES('003','3rd','Id=5, , , Id ')
INSERT INTO [Identity](Number,Name,Description) VALUES('004','4th','Id=7 not 5, ')
-- ,
SELECT * FROM [Identity]
결과:(1 줄 영향)메시지 8152,단계 16,상태 14,3 줄 은 문자열 이나 바 이 너 리 데 이 터 를 차단 합 니 다.문장 이 종료 되 었 습 니 다.1 줄 영향)(3 줄 영향)Id Number Name Password Description 1 001 1st 123 Id=1,시작 값 1 3 002 2nd 123 Id=3,시작 값 1,보폭 2 7 004 4th 123 Id=7 not 5,세 번 째 기록 삽입 실패 로 두 번 째 방식,GUID 즉 Globally Unique Identifier,UUID(Universally Unique IDentifier)라 고도 부 르 며 전 세계 에서 유일한 식별 자,GUID 는 일반적으로 네트워크 카드 주소,시간 및 기타 정 보 를 포함 하 는 32 비트 16 진수 의 수치 로 구성 된다.어떤 두 대의 컴퓨터 도 똑 같은 GUID 를 만 들 지 못 한다.그의 장점 은 유일 성 이다.데이터 베 이 스 를 통합 해 야 할 때 많은 노동력 을 절약 할 수 있다.예 를 들 어 본사 와 지사 가 각각 시스템 을 독립 적 으로 운영 하고 모든 지사 의 데 이 터 는 정기 적 으로 본사 에 제출 해 야 한다.데 이 터 를 합병 할 때 키 충돌 문 제 를 피 할 수 있 고 GUID 는 자체 성장 표지 피 드 의 특징 도 가지 기 때문에 개발 자 들 이 너무 많은 관심 을 가 질 필요 가 없다.그러나 GUID 정 보 량 이 많 고 사용 공간 도 넓 으 며 관련 검색 을 할 때 효율 성 이 높 지 않 을 것 으로 예상 되 며 32 비트 의 16 진법 에 대해 서도 가 독성 이 떨어진다.메 인 키 는 사용자 에 대한 무의식 적 이지 만 디자인 이나 디 버 깅 커 뮤 니 케 이 션 을 할 때 불편 하 다.장기 적 으로 데이터 의 이식 성 을 확보 하기 위해 서 는 일반적으로 GUID 를 메 인 키 로 사용한다.예(MsSQL):
--
CREATE TABLE GUID(
Id UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,--
Number VARCHAR(20) UNIQUE NOT NULL,
Name VARCHAR(20) NOT NULL,
Password VARCHAR(20) DEFAULT(123)
)
--
INSERT INTO GUID(Id,Number,Name) VALUES(NewID(),'001','1st')
INSERT INTO GUID(Id,Number,Name) VALUES(NewID(),'002','2nd')
INSERT INTO GUID(Id,Number,Name) VALUES(NewID(),'003','3rd')
-- ,
SELECT * FROM GUID
결과:Id Number Name Password 8E194F55-B4D3-4C85-8667-33BC6CD33BBC 001 1st 123 7141 F202-7D0E-4992-9164-5043 EC9FC6F 6 002 2nd 123 E0e365A 0-8748-4656-AF24-5D0B216D 2095 003 3rd 123 세 번 째 방식 으로 개발 하여 만 들 었 는데 편리 성 은 통제 성 을 가진다.이 통제 성 은 그 구성 형식 을 말 하 는데 성형 할 수도 있 고 문자 형 일 수도 있다.실제 상황 에 따라 다양한 구성 과 생 성 형식 을 줄 수 있 습 니 다.여기 서 어떤 친구 들 은 자동 으로 단일 번 호 를 생 성 할 수 있 습 니 다.예 를 들 어 20120716001 이나 PI-201207-0001 등 이 있 습 니 다.맞습니다.자기 생 성 은 이런 유사 한 응용 에 도 적 용 됩 니 다.자기 생 성에 대해 말하자면 대부분이 Max(Id)+1 을 먼저 생각 하 는데 이런 방식 은 편리 하지만 실제 적 으로 맞 춤 형(단일 번호 와 같은 의미 있 는 정 보 를 생산 할 때 이런 수요 가 있 을 수 있 고 메 인 키 는 필요 없다)과 병행 처리 가 좋 지 않다.예 를 들 어 현재 표 의 최대 번 호 는 1000 입 니 다.C1 과 C2 사용자 가 이 Id 를 동시에 취 할 때 얻 은 것 은 모두 1001 이 고 저장 에 실 패 했 습 니 다.일반적인 방법 은 값 을 추출 할 때 자 물 쇠 를 채 우 는 것 이지 만 여러 사용자 가 자주 조작 할 때 성능 은 매우 큰 문제 이다.그 중에서 주요 원인 중 하 나 는 직접 조작 하 는 업무 데이터 시트 이다.이러한 상황 에 대해 솔 루 션 은 키 시트 를 사용 하여 표 이름,현재 또는 다음 Id 및 기타 정 보 를 저장 하 는 것 입 니 다.시스템 에 있 는 여러 표 Id 가 모두 이런 방식 을 사용 하면 키 시트 에 해당 하 는 규칙 기록 이 여러 개 있 습 니 다.물론 전체 데이터베이스 의 모든 표 의 Id 가 같은 규칙 에 따라 하나의 소스 에서 생 성 될 수 있 습 니 다.그러면 키 시트 에는 하나의 규칙 기록 만 있 으 면 됩 니 다.키 시트 예 를 사용 하 는 변 화 를 살 펴 보 겠 습 니 다(MsSQL):
--
CREATE TABLE KeyTable(
ID INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
TCode VARCHAR(20) UNIQUE NOT NULL,
TName VARCHAR(50) NOT NULL,
TKey INT NOT NULL,
)
GO
--
INSERT INTO KeyTable(TCode,TName,TKey)
VALUES('T001','Test',0)
GO
-- ID ,
CREATE PROCEDURE UP_NewTableID
@TCode VARCHAR(20),@NextID INT OUTPUT
AS
DECLARE @CurTKey INT,@NextTKey INT
BEGIN TRAN TransID
SELECT @CurTKey=TKey
FROM KeyTable
WHERE TCode = @TCode
IF @@ROWCOUNT = 0
BEGIN
ROLLBACK TRAN TransID
RAISERROR('Warning: No such row is exists',16,1)
RETURN
END
SET @NextTKey = @CurTKey + 1
--WAITFOR DELAY '00:00:05'
UPDATE KeyTable
SET TKey = @NextTKey
WHERE TCode = @TCode
IF @@ROWCOUNT = 0
BEGIN
ROLLBACK TRAN TransID
RAISERROR('Warning: No such row is updated',16,1)
RETURN
END
COMMIT TRAN TransID
SET @NextID = @NextTKey
GO
저장 과정 을 수행 합 니 다 UP뉴 태 블 릿 ID:
DECLARE @NextID INT
EXEC UP_NewTableID 'T001',@NextID OUTPUT
PRINT @NextID
가 실 행 될 때 정상 적 이 고 얻 은 결과 도 정확 합 니 다.그러나 높 은 병발 상황 에서 여러 사용자 가 같은 ID 를 가 져 올 수 있 습 니 다.가 져 온 ID 가 해당 표 의 기록 을 저장 하 는 데 사용 된다 면 최대 한 사용자 만 저장 할 수 있 습 니 다.다음은 동시 다발 상황 을 모 의 하여 위의 저장 과정 UP뉴 태 블 릿 ID 에서 WAITFOR DELAY'00:00:05'라 는 주석 을 지우 고 검색 분석 기의 창 3 개 를 열 어 위 문장 을 순서대로 실행 합 니 다.각각 1,2,3 을 얻 으 려 는 것 으로 예상 되 지만 여러 창의 운행 결 과 는 1 일 수도 있 습 니 다.즉,업데이트 문 구 를 실행 하기 전에 모두 가 가 져 온 ID 가 0 이기 때문에 다음 수 치 는 모두 1 이다.(실제 수 치 는 DELAY 의 매개 변수 크기 와 운행 시간 에 따라 간격 이 연 관 됩 니 다)이런 점 에서 분석 하면 업데이트 문 구 를 실행 할 때 ID 가 원본 ID 인지 아 닌 지 를 판단 할 수 있 을 것 이 라 고 생각 하 는 친구 가 있 을 수 있 습 니 다.수정 과정:
ALTER PROCEDURE UP_NewTableID
@TCode VARCHAR(20),@NextID INT OUTPUT
AS
DECLARE @CurTKey INT,@NextTKey INT
BEGIN TRAN TransID
SELECT @CurTKey=TKey
FROM KeyTable
WHERE TCode=@TCode
IF @@ROWCOUNT=0BEGIN
ROLLBACK TRAN TransID
RAISERROR('Warning: No such row is exists',16,1)
RETURN
END
SET @NextTKey=@CurTKey+1
WAITFOR DELAY '00:00:05'
UPDATE KeyTable
SET TKey=@NextTKey
WHERE TCode=@TCode AND TKey=@CurTKey-- TKey
IF @@ROWCOUNT=0BEGIN
ROLLBACK TRAN TransID
RAISERROR('Warning: No such row is updated',16,1)
RETURN
END
COMMIT TRAN TransID
SET @NextID=@NextTKey
GO
3 개의 실행 과정 을 열 어 동시 다발 을 모 의 하면 2 개의 창 이 나타 납 니 다.메시지 50000,레벨 16,상태 1,과정 UP뉴 태 블 릿 ID,28 번 째 줄 Warning:No such row is updated 를 통 해 알 수 있 듯 이 동시 다발 로 인해 사용자 작업 이 실 패 했 지만 이전 보다 오류 가 발생 하 는 시간 을 앞 당 겼 습 니 다.그러면 더 좋 은 방법 이 있 습 니까?조회 부터 업데이트 까지 전체 사 무 를 끝 내 는 과정 에서 다른 사무 가 삽입 되 어 방해 하 는 방법 이 없 을 것 입 니 다.답 이 명확 하고 있 습 니 다.자 물 쇠 를 사용 하 세 요!적당 한 자 물 쇠 를 선택해 야 합 니 다.그렇지 않 으 면 효과 가 위 와 같 습 니 다.
ALTER PROCEDURE UP_NewTableID
@TCode VARCHAR(20),@NextID INT OUTPUT
AS
DECLARE @CurTKey INT,@NextTKey INT
BEGIN TRAN TransID
SELECT @CurTKey=TKey
FROM KeyTable WITH (UPDLOCK)-- ,
WHERE TCode=@TCode
IF @@ROWCOUNT=0BEGIN
ROLLBACK TRAN TransID
RAISERROR('Warning: No such row is exists',16,1)
RETURN
END
SET @NextTKey=@CurTKey+1
WAITFOR DELAY '00:00:05'
UPDATE KeyTable
SET TKey=@NextTKey
WHERE TCode=@TCode-- TKey SELECT
COMMIT TRAN TransID
SET @NextID=@NextTKey
GO
N(N>=2)개의 창 을 열 어 테스트 할 수 있 습 니 다.모든 조작 이 직렬 화 되 어 있 는 것 을 볼 수 있 습 니 다.결 과 는 우리 가 원 하 는 것 과 같 습 니 다.이렇게 주석 을 달 거나 모 방 된 문 구 를 없 애 면 WAITFOR DELAY'00:00:05'가 됩 니 다.앞에서 말 한 바 와 같이 이것 은 증빙 번호 와 유사 한 인 코딩 의 생 성 형식 에 도 적응 되 며,앞의 코드 와 키 시트 를 조금 만 수정 하면 됩 니 다.관심 있 는 친 구 는 한번 해 볼 수 있 습 니 다.전단 에서 이 번 호 를 얻 고 각 기록 에 적용 한다 면 점프 번호 가 있 을 수 있 습 니 다.점프 번호 가 존재 하지 않도록 하기 위해 서 는 점프 번호 표를 사용 하여 점프 번호 기록 을 정기 적 으로 스 캔 하여 다른 기록 에 적용 하 는 것 이 해결책 이다.또 다른 해결 방안 은 기 록 된 저장 작업 을 번호 가 발생 하 는 과정 에 놓 아 직렬 화 된 사 무 를 만 드 는 것 이다.속담 에 무 와 배 추 는 각자 좋아 하 는 것 이 있다 고 하 는데,당신 이 어떤 것 을 쓰 는 지 는 당신 의 도리 가 있 습 니 다.