[ruby-on-rails] Ruby on Rails ActiveRecord 마이그레이션에서 너무 긴 색인 이름을 어떻게 처리합니까?

네 개의 관련 테이블의 외래 키에서 생성되는 고유 인덱스를 추가하려고합니다.

add_index :studies,
  ["user_id", "university_id", "subject_name_id", "subject_type_id"],
  :unique => true

인덱스 이름에 대한 데이터베이스 제한으로 인해 마이그레이션이 실패합니다. 오류 메시지는 다음과 같습니다.

테이블 ‘studies’의 인덱스 이름 ‘index_studies_on_user_id_and_university_id_and_subject_name_id_and_subject_type_id’가 너무 깁니다. 한도는 64 자입니다

이것을 어떻게 처리 할 수 ​​있습니까? 다른 색인 이름을 지정할 수 있습니까?



답변

다음 과 같은 :name옵션을 제공하십시오 add_index.

add_index :studies,
  ["user_id", "university_id", "subject_name_id", "subject_type_id"],
  :unique => true,
  :name => 'my_index'

블록 에서 :index옵션을 사용하는 경우 값 과 동일한 옵션 해시를 사용합니다.referencescreate_tableadd_index

t.references :long_name, index: { name: :my_index }


답변

create_table블록 내의 열 정의에서 색인 이름을 변경할 수도 있습니다 (예 : 마이그레이션 생성기에서 가져옴).

create_table :studies do |t|
  t.references :user, index: {:name => "index_my_shorter_name"}
end


답변

PostgreSQL 에서 기본 제한은 63 자 입니다. 인덱스 이름은 고유해야하기 때문에 약간의 규칙을 사용하는 것이 좋습니다. 나는 (더 복잡한 구조를 설명하기 위해 예를 조정했다) :

def change
  add_index :studies, [:professor_id, :user_id], name: :idx_study_professor_user
end

일반적인 색인은 다음과 같습니다.

:index_studies_on_professor_id_and_user_id

논리는 다음과 같습니다.

  • index 된다 idx
  • 단수 테이블 이름
  • 참여 단어가 없습니다
  • 아니 _id
  • 알파벳 순서

일반적으로 어떤 일을합니까?


답변

당신은 또한 할 수 있습니다

t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')

Ruby on Rails API 에서와 같이 .


답변

이전 답변과 비슷합니다. 일반 add_index 줄과 함께 ‘name’키를 사용하십시오.

def change
  add_index :studies, :user_id, name: 'my_index'
end


답변

이러한 솔루션 중 어느 것도 나를 위해 일한 것이 두렵습니다. 아마도 내가 belongs_tocreate_table 마이그레이션에서 다형성 연관을 사용했기 때문일 것 입니다.

아래에 코드를 추가하고 다형성 연결과 관련하여 ‘색인 이름이 너무 깁니다’를 검색 할 때 다른 사람이 우연히 발견하는 경우 도움이되는 솔루션에 대한 링크를 추가하겠습니다.

다음 코드는 저에게 효과적이지 않았습니다.

def change
  create_table :item_references do |t|
    t.text :item_unique_id
    t.belongs_to :referenceable, polymorphic: true
    t.timestamps
  end
  add_index :item_references, [:referenceable_id, :referenceable_type], name: 'idx_item_refs'
end

이 코드는 저에게 효과적입니다.

def change
  create_table :item_references do |t|
    t.text :item_unique_id
    t.belongs_to :referenceable, polymorphic: true, index: { name: 'idx_item_refs' }

    t.timestamps
  end
end

이것은 나를 도와 준 SO Q & A입니다 : https://stackoverflow.com/a/30366460/3258059


답변

이 문제가 있었지만 timestamps기능이 있습니다. updated_at에서 63 자 제한을 초과하는 인덱스를 자동 생성했습니다.

def change
  create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
    t.timestamps
  end
end

테이블 ‘toooooooooo_loooooooooooooooooooooooooooooong’의 색인 이름 ‘index_toooooooooo_loooooooooooooooooooooooooooooong_on_updated_at’이 (가) 너무 깁니다. 한도는 63 자입니다

timestamps색인 이름을 지정하는 데 사용하려고했습니다 .

def change
  create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
    t.timestamps index: { name: 'too_loooooooooooooooooooooooooooooong_updated_at' }
  end
end

그러나,이 모두에 인덱스 이름을 적용하려고 updated_at하고 created_at필드 :

테이블 ‘toooooooooo_loooooooooooooooooooooooooooooong’의 색인 이름 ‘too_long_updated_at’이 이미 존재합니다

마침내 나는 포기 timestamps하고 타임 스탬프를 먼 길로 만들었습니다.

def change
  create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
    t.datetime :updated_at, index: { name: 'too_long_on_updated_at' }
    t.datetime :created_at, index: { name: 'too_long_on_created_at' }
  end
end

이것은 효과가 있지만 timestamps방법으로 가능하다면 듣고 싶습니다 !