Ger Hayden Ответов: 1

Как установить более длинный первичный ключ 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

Может быть, так оно и есть. Мне нужно будет прочитать его немного более внимательно, но на первый взгляд он выглядит многообещающим.

1 Ответов

Рейтинг:
2

Christian Graus

Это действительно ужасный первичный ключ. Почему бы вам просто не поместить GUID куда-нибудь и не создать его в качестве индекса?


Ger Hayden

Вы можете обсудить это с Броком Алленом и Домиником Байером в IdentityServer.io - это миграция из их образца кода. Мое единственное вмешательство состояло в том, чтобы применить его к MySql.

Richard MacCutchan

Черт возьми, Кристиан, ты вернулся всего день назад, а тролли уже набросились на тебя.

Christian Graus

И это было до того, как я начал тыкать фанатиков палкой.....

Ger Hayden

Не мог бы кто - нибудь, пожалуйста, провести аудит моего взаимодействия с этим форумом и указать, что отличает меня как тролля- или фанатика? Ни то, ни другое не является тем, чем я намеренно намеревался бы стать. Если в моем ответе на это решение и была ошибка, то она заключается в том, что этот ключ берет свое начало в Microsoft, а не в Identity Server. Решение, предлагаемое в этой теме, является одновременно бесполезным и бесполезным. Я перестал искать его на Stackoverflow, потому что устал читать критику ключевого выбора, а не пытаться объяснить, почему 1 + 1 > 4. Слава GKP1992 за то, что он действительно выкопал один из них.

Christian Graus

Я не говорил, что ты фанатик. Кто-то заметил, что вы были саркастичны, когда я указал, что по определению решение, которое вы преследуете, ужасно. Я не расстроена. Расслабиться.

Ger Hayden

Проблема в том, что я недостаточно уверен в себе, чтобы пойти менять указанный ключ и рисковать попасть в шестеренки Identity Server или Microsoft Identity. Мой первоначальный ответ проистекает в такой же степени из разочарования этим ограничением, как и любой другой. Также к твоей чести, именно Ричард использовал слово "Т".

Christian Graus

Почему Identity Server или Microsoft Identity заботятся о макете вашей базы данных помимо таблиц, которые использует Identity?

Ger Hayden

Это не. Оскорбительная таблица, "aspnetuserlogins", которая была частью миграции, поставляемой с примерами сервера идентификации. Я сделал найти все на пример, чтобы проиллюстрировать этот ответ. На него всегда ссылаются только при миграции, как и в случае с другими таблицами, связанными с идентификаторами. Он использует механизм Microsoft Identity для управления своими данными. Использование другого ключа к этому столу отпугивает меня. Я пошел на сокращение длины существующих ключевых компонентов.

Тем не менее, это взаимодействие становится все более полезным, поскольку оно заставляет меня думать - у меня есть 90-минутное окно два раза в день для этого материала, и оно потребляется большую часть сегодняшнего утра. Поскольку мы говорим здесь о ключе, изменение, которое я сделал в сокращении длины ключевых компонентов, связано с риском. Добавляя столбец и считая его ключевым, скажем, Guid в соответствии с вашим предложением. Это ничего не сломает, потому что идентичность не ищет его, особенно если я использую то же самое имя, это гарантирует, что любая ссылка на него есть. Возможно, мне понадобится какое-то волшебство под капотом, чтобы убедиться, что если есть запрос, основанный на нем, то извлекаются те же самые данные.

Christian Graus

Да, часто обсуждение вашей проблемы помогает, потому что вы понимаете, что есть другой способ ее решить :)

Я думаю, что ваша основная проблема заключается в отсутствии длины ключа в MySQL. Если эти два столбца являются идентификаторами GUID (но на самом деле строками в Identity), то можно найти руководства в интернете, чтобы изменить эти ключи (обычно строго ввести их как GUID, но нет никаких причин, по которым вы не могли бы изменить их на Long, например)