我试图理解一个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
那这是做什么的?首先,让我们看一下多态。多态将在产品中创建vendor_type VARCHAR(255)和vendor_id INT列。我相信VARCHAR设置为256个字符,因为早期的MySQL版本不支持更多字符。但是请记住,数据库中的VARCHAR列的长度是可变的,因此VARCHAR(255)与VARCHAR(20)的十个字符的值没有存储优势。
references将供应商类型和供应商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
开suppliers
(supplier_type
)
因此,我们拥有的是vendor_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
答案 0 :(得分:0)
排序规则只是命令,真正的原因是字符集。 This answer显示了一些解决方法。像您一样完成索引限制也可以。
从255开始,很长时间以来(MySQL-4.0)varchar限制-其rather and arbitrary choice和基于数据的限制选择是最好的方法。
除了索引长度更大而长度更大时,涉及这些索引的联接有时还会使用MEMORY存储引擎,从而导致将varchar(X)转换为char(X),从而可以使用更多的内存。