Как установить более длинный первичный ключ mysql, чтобы 1600 соответствовал 3072
У меня был сбой миграции ядра ef с длиной ключа, слишком долго предназначавшейся для MySql.
Та же самая миграция успешно нацелена на SqlSever. Как мне обойти это в MySql?
Когда я применяю первичный ключ непосредственно с помощью MySql Workbench, я получаю ту же проблему.
Оба ключевых компонента имеют длину 767, и ошибка утверждает, что ключ должен быть меньше 3072, поэтому я не уверен, почему я его вижу. Поиск в интернете предполагает, что это проблема кодирования, потому что только на числах комбинированная длина менее 1600 должна помещаться внутри 3072. Настройка в workbench advised, где предлагается что-либо помимо критики ключевого выбора, не появляется в моей версии.
Как изменить кодировку так, чтобы составной ключ 1600 не превышал лимит 3072?
Это определения столбцов:
LoginProvider varchar(767) нет
ProviderKey varchar(767) нет
ProviderDisplayName текст да
UserId varchar(767) нет
Комбинированная длина ключа меньше 1600, поэтому он должен быть удобно расположен внутри предела 3072, но я считаю, что кодировка символов вступает в игру, чтобы вывести его за пределы этого. Я не могу понять, как добиться успеха в миграции.
Некоторые предпосылки
Эта миграция происходит из комбинированного примера на веб-сайте IdentityServer: здесь
Это исходный код из миграции EF из моей целевой копии MySQL:
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b => { b.Property<string>("LoginProvider") .HasMaxLength(767); b.Property<string>("ProviderKey") .HasMaxLength(767); b.Property<string>("ProviderDisplayName"); b.Property<string>("UserId") .IsRequired(); //b.HasKey("LoginProvider", "ProviderKey"); b.HasIndex("UserId"); b.ToTable("AspNetUserLogins"); });
Это соответствующий код из опубликованного примера таргетинга SqlServer:
migrationBuilder.CreateTable( name: "AspNetUserLogins", columns: table => new { LoginProvider = table.Column<string>(nullable: false), ProviderKey = table.Column<string>(nullable: false), ProviderDisplayName = table.Column<string>(nullable: true), UserId = table.Column<string>(nullable: false) }, constraints: table => { table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); table.ForeignKey( name: "FK_AspNetUserLogins_AspNetUsers_UserId", column: x => x.UserId, principalTable: "AspNetUsers", principalColumn: "Id", onDelete: ReferentialAction.Cascade); });
Явно отличается, но, запустив его, я извлек инструкцию create из среды Sql Server Management Studio
/****** Объект: таблица [dbo].[AspNetUserLogins] Дата написания сценария: 16-Apr-19 6:42:24 AM ******/
УСТАНОВИТЕ ANSI_NULLS НА
ГО
УСТАНОВИТЕ QUOTED_IDENTIFIER НА
ГО
Создайте таблицу [dbo].[AspNetUserLogins](
[LoginProvider] [nvarchar](450) NOT NULL,
[ProviderKey] [nvarchar](450) NOT NULL,
[ProviderDisplayName] [nvarchar](max) NULL,
[UserId] [nvarchar](450) NOT NULL,
Ограничение [PK_AspNetUserLogins] первичный ключ КЛАСТЕРИЗОВАН
(
[LoginProvider] ASC,
[ProviderKey] ASC
)С (КАК = ВЫКЛ, STATISTICS_NORECOMPUTE = OFF, ТО ЗНАЧЕНИЕ IGNORE_DUP_KEY = OFF, ТО ПАРАМЕТРЫ ALLOW_ROW_LOCKS = ON, ТО ALLOW_PAGE_LOCKS ИНСТРУКЦИИ =) НА [ОСНОВНОЙ]
) НА [ОСНОВНОЙ] ВЫРАЖЕНИЯХ TEXTIMAGE_ON [ПЕРВИЧНЫЙ]
ГО
Длина ключа суммируется до 900 в SqlServer, но максимум, который я могу получить от MySql, - это 768.
Это еще до того, как я рассмотрю миграции для двух других контекстов в этом примере. Они полностью провалились под MySQL и прямо сейчас все что я вижу это извлечение инструкций create и перевод SQL вручную
Что я уже пробовал:
Я пробовал как миграцию ядра EF, так и непосредственно через MySQL workbench:
Проведение:
ALTER TABLE `identityserver_003`.`aspnetuserlogins`
Добавить первичный ключ ('LoginProvider`, `ProviderKey`);
;
Ошибка 1071: указанный ключ был слишком длинным; максимальная длина ключа составляет 3072 байта
инструкция SQL:
ALTER TABLE `identityserver_003`.`aspnetuserlogins`
Добавить первичный ключ ('LoginProvider`, `ProviderKey`)
Операция не удалась: произошла ошибка при применении SQL-скрипта к базе данных.
Я могу преодолеть это, только сократив длину двух варчаров до 384. Системная переменная innodb_large_prefix недоступна, поэтому рекомендации по ее изменению неприменимы.
Это моя версия информации
innodb_version 8.0.12
версия 10
slave_type_conversions
tls_version в протоколе TLSv1,в протоколе TLSv1.1,в протоколе TLSv1.2
версия 8.0.12
version_comment MySQL Community Server - GPL
version_compile_machine архитектуру x86_64
version_compile_os х64
version_compile_zlib 1.2.11
ZurdoDev
Я в замешательстве. Если я правильно вас понял, Вы превысили лимит в MySql. Итак, что вы хотите от нас?
Ger Hayden
Чтобы быть точным, как я могу изменить кодировку так, чтобы составной ключ 1600 не превышал лимит 3072? Я обновил вопрос с более подробной информацией.
GKP1992
Это может оказаться полезным.
[^]
Кроме того, nvarchar использует 2 байта на символ, тогда как varchar использует 1. Выявлена прямая корреляционная зависимость успеха на 368 и сбой по 767 достаточно свидетельствует о том, что.
Ger Hayden
Может быть, так оно и есть. Мне нужно будет прочитать его немного более внимательно, но на первый взгляд он выглядит многообещающим.