如何将 MySQL 数据库从 v5.7.19 部署到 v5.5.6 的远程 MySQL 数据库

这实际上是我的错,我之前没有想到,我的远程服务器MySQL版本(在共享主机上)是,但我的本地MySQL版本是。5.5.65.7.19


我开发了一个Laravel()Web应用程序,在第一次运行时就运行了迁移,但由于它完全是一个个人项目,我继续手动修改数据库的位置和方式,(但是不记录,我也一直在更改迁移文件,尽管我从未在第一个实例之后运行过它们)。v6.6.0


我从其他一些表中迁移了所有数据,我的应用程序已准备好部署。但是,当我导出本地数据库表并将其导入远程数据库时,它给了我一个众所周知的错误:


指定的密钥太长;最大密钥长度为 767 字节


我实际上忽略了它,因为所有表都很好地导入了。但最近我发现了它的警告 - 所有和都不存在在我的远程数据库中。AUTO_INCREAMENTPRIMARY_KEY


我搜索了我所能搜索的内容,但所有的解决方案都建议删除数据库并使用UTF-8再次创建它,实际上不可能是我的情况。像下面的PHP-way这样的解决方案也不是我的情况,因为我在收到错误时使用PHPMyAdmin导入我的表:


// File: app/Providers/AppServiceProvider.php

use Illuminate\Support\Facades\Schema;


public function boot() 

{

    Schema::defaultStringLength(191); 

}

我还尝试在目标数据库上运行以下命令:


SET @global.innodb_large_prefix = 1;

但是没有运气。我还尝试替换本地文件的所有实例:.sql


从 到 和utf8mb4utf8

从 到utf8mb4_unicode_ciutf8_general_ci

但又没有找到运气。


错误具体来自哪里,实际上更长的外键,如,在这个阶段,当一切都完成时,我不知道如何重构所有外键以兼容。xy_section_books_price_unit_id_foreign5.5


任何人都可以对我的问题进行一些阐述吗?


如何部署本地数据库()而不会丢失MySQL数据库,外键和es以保持数据完整?v5.7PRIMARY_KEYINDEXv5.5


慕慕森
浏览 95回答 2
2回答

回首忆惘然

更改密钥名称。您可以在创建“默认生成”的很长的键名时覆盖它们。有关文档,请参阅 https://laravel.com/docs/5.8/migrations 可用索引类型从SQL服务器迁移到MySQL时,我遇到了类似的问题,并且具有完整长命名空间和键名称的自动生成的键名称太长了。因此,通过用手工制作的唯一索引名称替换所有这些名称,我解决了这些问题。在MySQL中,你并不需要唯一的名称,但是如果你使用SQLITE进行单元测试,你确实需要唯一的名称。所以而不是:public function up() {   ....   $table->primary('id');  // generates something like work_mayeenul_islam_workhorse_models_model_name_id_primary_key   $table->index(['foobar','bazbal']);   // generates something like work_mayeenul_islam_workhorse_models_model_name_foobar_bazbal_index}您使用自己定义的,您知道这些是短索引名称。public function up() {   ....   $table->primary('id', 'PK_short_namespace_modelname_id');   $table->index(['foobar', 'bazbal'], 'IX_short_namespace_modelname_foobar_bazbal');}

海绵宝宝撒

我的问题是,我无法再运行,因为我在这些表上有实时数据。首先,这个问题让我学到了新的东西(感谢我的同事Nazmul Hasan):php artisan migrate经验教训密钥是唯一的,但甚至可能是胡言乱语首先,我在外键中发现了一个模式:.类似地,在索引键中:。吸取的教训是,外键或索引键不必采用这种格式即可工作。它必须是独一无二的,但它可以是任何东西,也可能是胡言乱语。所以钥匙可以很容易地是或其他任何东西。{table_name}_{column_name}_foreign{table_name}_{column_name}_indexpassword_resets_email_indexpre_idx但这不是问题所在。溶液对于解决方案,我尝试逐个表地挖掘文件表,并按作用域挖掘文件。我发现只有2个密钥声明显示阻止错误。还有另外3次出现警告:.sqlUNIQUEALTER TABLE `contents` ADD KEY `contents_slug_index` (`slug`); --- throwing warningALTER TABLE `foo_bar` ADD UNIQUE KEY `slug` (`slug`); --- throwing errorALTER TABLE `foo_bar` ADD KEY `the_title_index` (`title`) USING BTREE; --- throwing warningALTER TABLE `password_resets` ADD KEY `password_resets_email_index` (`email`); --- throwing waringALTER TABLE `users` ADD UNIQUE KEY `users_email_unique` (`email`); --- throwing error最后,解决方案来自这个特定的StackOverflow线程:INNODB VARCHAR(255)utf8INNODB VARCHAR(191)utf8mb4通过对这些表进行检查,了解SO线程,我发现:问题是:在MySQL 5.5 / 5.6中使用排序规则时,字段值不能大于。但utf8mb4_unicode_ci191使用 MySQL 5.5/5.6 中的排序规则,字段值不能大于 。但你不能保存表情符号等。utf8_unicode_ci255utf8_unicode_ci所以我决定继续使用相对较长的值。因此,对于临时补救措施:utf8_unicode_ci我更改了所有这些特定的列,我从更改为utf8mb4_unicode_ciutf8_unicode_ci如果这些特定列超过 255,我将它们减少到 255例如,如果表格如下所示:CREATE TABLE `foo_bar` (  `id` bigint(20) UNSIGNED NOT NULL,  `cover` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL,  `title` varchar(300) COLLATE utf8mb4_unicode_ci NOT NULL,  `slug` varchar(300) COLLATE utf8mb4_unicode_ci NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;我只更改了必要的列:CREATE TABLE `foo_bar` (  `id` bigint(20) UNSIGNED NOT NULL,  `cover` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL,  `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,  `slug` varchar(255) COLLATE utf8_unicode_ci NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;就是这样。这种临时补救措施工作正常,我不必更改外键或索引键。为什么采取这种临时补救措施?因为最终我会使用MySQL 5.7 +,但在此之前,至少要尝试应对以前的版本。
打开App,查看更多内容
随时随地看视频慕课网APP