Я пытаюсь понять ошибку MySQL, и она связана с некоторыми настройками по умолчанию, которые Rails генерирует с миграциями ActiveRecord.Учитывая это:
rails generate migration AddDetailsToProducts supplier:index:references{polymorphic}
class AddDetailsToProducts < ActiveRecord::Migration
def change
add_reference :products, :supplier, polymorphic: true, index: true, foreign_key: true
end
end
Так, что это делает?Сначала давайте посмотрим на полиморфизм.Polymorphic создаст в продуктах столбцы VARCHAR (255) и тип_поставщика supplier_type.Я считаю, что VARCHAR установлен на 256 символов, так как ранние версии MySQL не поддерживали больше.Но помните, что столбцы VARCHAR в базе данных имеют переменную длину, поэтому нет преимущества в хранении десятизначного значения в VARCHAR (255) по сравнению с VARCHAR (20). В ссылках
добавлены supplier_type и supplier_id в качестве внешних ключейпродуктов для поставщиков первичный ключ.FOREIGN KEY - это поле (или набор полей) в одной таблице, которое ссылается на PRIMARY KEY в другой таблице.Это ключ, используемый для связывания двух таблиц.
Так что я думаю, что add_reference делает что-то вроде этого:
CREATE TABLE products (
PRIMARY KEY (id),
FOREIGN KEY (supplier_id) REFERENCES suppliers(id)
FOREIGN KEY (supplier_type) REFERENCES suppliers(id)
)
CREATE INDEX `index_suppliers_on_supplier_type` ON `suppliers` (`supplier_type`)
CREATE INDEX `index_suppliers_on_supplier_id` ON `suppliers` (`supplier_id`)
Теперь я получил ошибку, подобную этой:
Указанный ключ был слишком длинным;максимальная длина ключа составляет 767 байт: CREATE INDEX index_suppliers_on_supplier_type
ON suppliers
(supplier_type
)
Итак, у нас есть столбец supplier_type, который является VARCHAR (255), и мы попытались разместитьИндекс на это.Я использую коалицию utf8_unicode_ci.Насколько я понимаю, это использует от 1 до 3 байтов на символ.Таким образом, даже если это будет использовать 3 байта для всех символов с максимум 256 символами, то есть 256 * 3 = 768. Один байт закончен.Это действительно не имеет смысла.Действительно ли решение состоит в том, чтобы просто добавить ограничение на максимальный размер символа для столбца?Я правильно понимаю?
Потому что, когда я это делаю, ошибка исчезает:
class ChangeSuppliers < ActiveRecord::Migration
def change
change_column :suppliers, :supplier_type, :string, limit: 191
end
end