在这种情况下,为什么我可以拥有超过767个字节的utf8mb4编码的mariadb(版本10.1.35)索引前缀?

1aaf6o9v  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(377)

我读过这个问题,我试着在我的案例中测试它,但我不明白为什么它会起作用。
我使用的是rails和utf8mb4编码的mariadb(版本10.1.35)
在我的模式中有这样一个:

create_table "settings", force: :cascade do |t|
    t.string   "var",         limit: 255,   null: false
    t.text     "value",       limit: 65535
    t.integer  "target_id",   limit: 4,     null: false
    t.string   "target_type", limit: 255,   null: false
    t.datetime "created_at",                null: false
    t.datetime "updated_at",                null: false
  end

  add_index "settings", ["target_type", "target_id", "var"],
       name: "index_settings_on_target_type_and_target_id_and_var",
       unique: true,
       length: {"target_type"=>191,
                "target_id"=>nil,
                "var"=>191}, using: :btree

我愿意 rake db:schema:load 一切顺利。我认为应该显示错误,因为innodb index prefix limit是767字节,在这种情况下我们超出了限制:
1914+1914=1528,超过767
有人能解释为什么它还能用吗?
我正在努力理解索引、索引键和索引前缀之间的区别。如果有人能为我列出一个资源来学习这些,那就太好了。
我读到:
https://dev.mysql.com/doc/refman/8.0/en/create-index.html#create-索引列前缀
https://github.com/turnkeylinux/tracker/issues/985
https://stackoverflow.com/a/3844913/6359753
https://www.wikiwand.com/en/database_index

p5fdfcr1

p5fdfcr11#

索引是保存信息以便直接(或更好地)访问行的对象。。为此,索引存储列值索引中涉及的列命名为key。。索引前缀是键中值的一部分(左侧字符串),用于减少索引的空间。(如果前缀始终相同,则表示无效)

191 x 4 = 764 (< 767)

192 x 4 = 768 (> 767)

值767是每个键的值,而不是总数
前缀支持和前缀长度(如果支持)取决于存储引擎。例如,innodb表的前缀长度可以高达767字节
https://dev.mysql.com/doc/refman/8.0/en/create-index.html
所以钥匙是191x4 target_type 钥匙是191x4 var 工作

ttisahbt

ttisahbt2#

索引的每列限制为767字节。
尽量避免使用索引前缀(例如, INDEX(foo(191) ),它几乎是无用的。请参阅此以了解一些解决方法。
这就是索引的样子吗?

UNIQUE(target_type(191), target_id, var(191))

如果是的话,还有另一个问题。唯一性约束将忽略中第一个191之后的字符 target_type 以及 var . 所以,你可能没有得到你所期望的。

相关问题