5

내 현재 레일 애플리케이션에서 "created_at"필드로 모델을 정렬하여 일정 충돌을 해결하고 있습니다. 그러나, 이것을 허용하는 폼에서 여러 개의 모델을 삽입 할 때, created_at 시간은 모두 정확히 동일하다는 것을 깨달았습니다.데이터베이스의 자동 증가 기본 키를 사용할 수 있습니까?

이것은 최고의 프로그래밍 방법에 대한 질문입니다. 응용 프로그램에서 데이터베이스의 ID 열을 사용하여 각 주문에 따라 INSERT을 더 크게 늘릴 수 있습니까? 다시 말하면, ID 열로 데이터베이스에서 꺼내는 행 그룹을 정렬하고 이것이 생성 순서에 기반한 정확한 정렬이라는 것을 확신 할 수 있습니까? 그리고 이것은 나의 적용에서 좋은 연습인가?

답변

1

데이터베이스 공급 업체에 따라 다릅니다.

MySQL 나는 절대적으로 자동 증가 키를 주문합니다. SQL Server 확실한 것은 아닌지 확신 할 수는 없지만 믿을 수는 있습니다.

문제가 발생하는 곳은이 기능을 지원하지 않는 데이터베이스입니다. 특히 오케스트레이션은 거의 순서대로 사용되는 시퀀스를 사용합니다.

다른 방법으로 생성 된 시간과 ID를 확인할 수 있습니다.

+0

나는 이중화에 대한 아이디어를 좋아하고 하나씩 정렬 한 다음 보조 정렬에 ID를 사용합니다. . . 감사! – BushyMark

+0

오라클 시퀀스는 대부분 비 RAC 설치를 위해 주문됩니다. –

2

생성 된 식별 번호는 고유합니다. PostgreSQL과 Oracle 에서처럼 Sequence를 사용하는지 또는 MySQL의 자동 증가와 같은 다른 메커니즘을 사용하는지에 관계없이.

그러나 시퀀스는 대부분 20 개 숫자와 같이 대량으로 수집됩니다. 그래서 PostgreSQL에서는 어떤 필드가 먼저 삽입되었는지를 결정할 수 없습니다. 삽입 된 레코드의 ID에는 틈이있을 수도 있습니다.

따라서 데이터베이스 구현 세부 정보에 의존하지 않기 위해 이와 같은 작업에 대해 생성 된 ID 필드를 사용하면 안됩니다.

는 명령 실행시 생성 또는 업데이트 필드를 생성하면 나중에 창조론자, 또는 업데이트시에 의해 정렬 훨씬 낫다. 예를 들어 가 :

INSERT INTO A (data, created) VALUES (smething, DATE()) 
UPDATE A SET data=something, updated=DATE() 
0

내가 선 사이에 읽으면 질문에 대한 대답은 ... 예 믿는다, 나는 당신이 시스템에 '실종'되는 ID의 번호를 다시 사용할 수 있음을 우려하고 생각 시퀀스, 그리고 따라서 ID 번호로 1,2,3,5,6,7을 사용했다면, 내가 알고있는 모든 구현에서 다음 ID 번호는 항상 8 (또는 그 이상)이지만, ID # 4 레코드가 누락되었다고 판단 할 수있는 DB를 알고 있으므로 해당 ID 번호를 다시 사용하십시오.

SQL Server에 대해 가장 잘 알고 있지만 시퀀스에서 간격을 채우는 공급 업체가 왜 항상 사용중인 ID 목록을 유지하는 오버 헤드를 생각하는지 마지막으로 사용 된 번호의 1을 더하고 1을 더합니다.

당신은 안전하게 고유하게 할당 된 다음 ID 번호에 의존 할 수 있습니다.

0

예 고유 ID는 아니며 정렬에 의존해서도 안됩니다. 행 고유성 만 보장해야합니다. 가장 좋은 방법은 Emktas가 지적한대로이 정보에 대해 별도의 "업데이트 된"또는 "만든"필드를 사용하는 것입니다.

는 생성 시간을 설정하려면, 당신은 단지 작성 시간을 담당 지금이

CREATE TABLE foo (
    id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL; 
    created TIMESTAMP NOT NULL DEFAULT NOW(); 
    updated TIMESTAMP; 
    PRIMARY KEY(id); 
) engine=InnoDB; ## whatever :P 

, 같은 기본 값을 사용할 수 있습니다. 업데이트 시간에 나는이 하나의 같은 AFTER의 UPDATE 트리거 제안 (별도의 쿼리에서 그것을 할 수 물론,하지만 트리거는, 내 의견으로는, 더 나은 솔루션입니다 - 더 투명) :

DELIMITER $$ 
CREATE TRIGGER foo_a_upd AFTER UPDATE ON foo 
FOR EACH ROW BEGIN 
    SET NEW.updated = NOW(); 
END; 
$$ 
DELIMITER ; 

그리고 그 일을해야합니다.

편집 : 와우는 나입니다. 어리석게도 mysql을위한 것이지, 함수 이름 (즉, 'NOW')과 다른 미묘한 itty-bitty의 차이가있을 수 있습니다. EJB의 대답에

+1

당신은 OP가 말한 것을 무시합니다 : 그는 이미 created_at 필드를 가지고 있으며, 동시에 여러 아이템이 삽입되었을 때 동일하다는 것입니다, 따라서 그의 질문입니다. – cletus

+0

사실 내 생각의 기차가 그 것처럼 거칠게 떠돌아 다니는 내 생각의 기차가 옆길로 걸어갔습니다. 죄송합니다. 물론 당신은 맞습니다. created_at에 의해 먼저 정렬 한 다음 id로 정렬하는 것이 가장 쉬운 해결책 일 수 있습니다 (아마도 올바른 순서를 엄격히 보장하지는 않지만 동일한 created_at 값을 가진 행이 각각 동일한 순서로 반환됨을 보장합니다). 시각). – shylent

0

한 가지주의 :

SQL 당신이 열을 기준으로 순서를 지정하지 않은 경우 주문의 보증을 제공하지 않습니다. 예 : 일부 초기 행을 삭제 한 다음 'em'을 삽입하면 새로운 행이 이전 위치의 db (새 ID 임에도 불구하고)의 동일한 위치에 살게되어 기본 정렬로 사용할 수 있습니다.

FWIW, 나는 일반적으로 ID별로 주문을 created_at의 주문 유효 버전으로 사용합니다. 그것은 datetime 필드에 인덱스를 추가 할 필요가 없다는 점에서 더 저렴합니다. (따라서 더 크고 따라서 간단한 정수 기본 키 인덱스보다 느립니다.) 다른 것으로 보장됩니다. 거의 같은 시간에 더해져 약간 다른 순서로 정렬됩니다.

0

이것은 아마도 DB 엔진에 의존합니다. DB가 어떻게 시퀀스를 구현하는지 확인하고 문서화 된 문제가 없다면 ID에 의존하기로 결정할 것입니다.

예. Postgresql sequence은 시퀀스 캐시 매개 변수로 재생하지 않는 한 정상입니다.

다른 프로그래머가 잘못된 ID 열이있는 다른 DB의 레코드를 수동으로 만들거나 복사 할 가능성이 있습니다. 그러나 나는 문제를 단순화 할 것이다. 누군가가 수동으로 데이터 무결성을 파괴 할 가능성이 낮은 경우를 걱정하지 마십시오. 모든 것을 보호 할 수는 없습니다.

제 조언은 시퀀스 생성 ID에 의존하고 프로젝트를 앞으로 옮기는 것입니다.

0

이론상 가장 높은 ID 번호가 마지막으로 생성됩니다. 데이터베이스에는 일시적으로 자동 생성 된 값 삽입을 끄고 일부 레코드를 수동으로 삽입 한 다음 다시 켜는 기능이 있음을 기억하십시오. 이 삽입은 일반적으로 프로덕션 시스템에서 사용되지 않지만 다른 시스템에서 많은 양의 데이터를 이동할 때 간혹 발생할 수 있습니다.

관련 문제