Как мне обрабатывать слишком длинные имена индексов при переходе на Ruby on Rails ActiveRecord?

250

Я пытаюсь добавить уникальный индекс, который создается из внешних ключей из четырех связанных таблиц (пользователей, университетов, subject_names, subject_types):

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

Ограничение MySQL для имени индекса приводит к остановке миграции. Вот сообщение об ошибке:

Индексное имя 'index_studies_on_user_id_and_university_id_and_subject_name_id_and_subject_type_id' в таблице "исследования" слишком велико; предел составляет 64 символа

Как я могу справиться с этим? Могу ли я использовать псевдоним?

Теги:
migration
indexing

5 ответов

418
Лучший ответ

Использование:

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

Дополнительная информация находится в add_index.

  • 2
    Согласно APIdock имя должно быть строкой, а не символом
  • 7
    Это также работает для ограничения в 63 символа Postgres.
Показать ещё 2 комментария
94

Вы также можете изменить имя индекса в определениях столбцов в блоке create_table (например, из генератора миграции).

create_table :studies do |t|
  t.references :user, index: {:name => "index_my_shorter_name"}
end
  • 5
    Обратите внимание, что это не создает многостолбцовый индекс из исходного вопроса; это просто демонстрация того, как сократить длинное имя индекса из create_table
  • 5
    Это помогло мне, когда я пытался создать полиморфную ссылку на таблицу с t.references :searchable, polymorphic:true, index: {:name => "index_searches_on_searchable"} с индексом t.references :searchable, polymorphic:true, index: {:name => "index_searches_on_searchable"} в этом случае индекс был фактически multi-column (searchable_id и searchable_type) и добавление пространства имен в сгенерированное имя стало очень длинным.
Показать ещё 2 комментария
21

В 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
  • Алфавитный порядок

Что обычно выполняет задание.

  • 1
    Спасибо, что поделился. Было бы неплохо, если бы вы могли связать документацию Postgres для факта ограничения.
  • 0
    Нужно ли нам имя таблицы в имени индекса, так как индекс все равно принадлежит этой таблице? Просто любопытно, если это полезно где-то я не видел.
Показать ещё 1 комментарий
11

Вы также можете сделать

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

как в Ruby on Rails API.

3

Как и в предыдущем ответе: просто используйте ключ "name" с вашей обычной линией add_index:

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню