데이터베이스 테이블의 중복 레코드 제거
기존 데이터가 있는 데이터베이스 테이블에 데이터베이스 수준의 고유 제약 조건(유니크 인덱스)을 도입하기 위한 전략을 설명합니다.
이 가이드는 데이터가 있는 기존 데이터베이스 테이블에 데이터베이스 수준의 고유 제약 조건(유니크 인덱스)을 도입하기 위한 전략을 설명합니다. 요구 사항: 관련 칼럼에 대한 속성 수정( INSERT , UPDATE )은 ActiveRecord를 통해서만 이루어집니다(이 기법은 AR 콜백에 의존합니다). 중복은 드물게 발생하며 주로 동시 레코드 생성으로 인해 발생합니다. teleport를 통해 프로덕션 데이터베이스 테이블을 확인하여 검증할 수 있습니다(도움이 필요하면 데이터베이스 메인테이너에게 문의하세요). 총 실행 시간은 주로 데이터베이스 테이블의 레코드 수에 따라 다릅니다. 마이그레이션은 모든 레코드를 스캔해야 하므로, 배포 후 마이그레이션 실행 시간 제한(약 10분)을 충족하려면 1,000만 행 미만의 데이터베이스 테이블을 소형 테이블로 간주할 수 있습니다. 소형 테이블의 중복 제거 전략 # 이 전략은 3단계 마일스톤이 필요합니다. 예시로, project_id 칼럼 기준으로 title 이 고유해야 하는 조건에서 issues 테이블을 title 칼럼 기반으로 중복 제거합니다. 마일스톤 1: 배포 후 마이그레이션(post-migration)을 통해 테이블에 새로운 데이터베이스 인덱스(유니크가 아닌)를 추가합니다(아직 없는 경우). 중복 발생 가능성을 줄이기 위해 모델 수준 고유성 검증을 추가합니다(아직 없는 경우). 중복 레코드 생성을 방지하기 위해 트랜잭션 수준의 어드바이저리 락(advisory lock) 을 추가합니다. 두 번째 단계만으로는 중복 레코드를 방지할 수 없습니다. 자세한 내용은 Rails 가이드 를 참조하세요. 인덱스 생성을 위한 배포 후 마이그레이션: def up add_concurrent_index :issues, [:project_id, :title], name: INDEX_NAME end def down remove_concurrent_index_by_name :issues, INDEX_NAME end Issue 모델 검증 및 어드바이저리 락: class Issue < ApplicationRecord validates :title, uniqueness: { scope: :project_id } before_validation :prevent_concurrent_inserts private # This method will block while another database transaction attempts to insert the same data. # After the lock is released by the other transaction, the uniqueness validation may fail # with record not unique validation error. # Without this block the uniqueness validation wouldn't be able to detect duplicated # records as transactions can't see each