mysql - 使用联合 utf8_unicode_ci 限制索引列的 VARCHAR 长度的必要性
问题描述
我试图理解一个 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
那么这有什么作用呢?首先,让我们看一下多态性。多态将在产品中创建供应商类型 VARCHAR(255) 和供应商 ID INT 列。我相信 VARCHAR 设置为 256 个字符,因为 MySQL 的早期版本不支持更多字符。但请记住,数据库中的 VARCHAR 列是可变长度的,因此 VARCHAR(255) 中的十个字符值与 VARCHAR(20) 相比没有存储优势。
引用将供应商类型和供应商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
ONsuppliers
(supplier_type
)
所以我们有一个供应商类型列,它是 VARCHAR(255),我们试图在它上面放置一个索引。我正在使用 utf8_unicode_ci 联合。我的理解是每个字符使用 1 到 3 个字节。因此,即使这是对最多 256 个字符的所有字符使用 3 个字节,也就是 256 * 3 = 768。超过一个字节。这真的没有意义。解决方案真的只是为列的最大字符大小添加限制吗?我是否正确理解这一点?
因为当我这样做时,错误消失了:
class ChangeSuppliers < ActiveRecord::Migration
def change
change_column :suppliers, :supplier_type, :string, limit: 191
end
end
解决方案
推荐阅读
- c++ - 如何判断表达式是在编译时还是运行时评估的?
- php - 为什么我的 html 代码不能正常工作
- angular - 滚动时鼠标离开时不会触发 Mouseleave 事件
- oracle - 如何在带有检查约束的 oracle 11g 中将日期与系统日期进行比较?
- codenameone - 侧边菜单和可滚动的表单/容器
- reporting-services - 如何解决我在 Visual Studio 报告中的表达式中除以零的错误?
- c# - 为什么 Entity Framework 由于 Boolean 和 Int 数据类型而无法查询该表?
- android - 当大小变为零时,后退按钮上的 findFragmentById 变为空白
- vue.js - 单击时如何从leafletjs折线中选择一条线?
- laravel - Laravel,faker:调用未定义的函数