unsignedBigInteger('discord_id')->nullable()->after('id'); }); // 2. Migrate Discord Users IDs DB::table('users') ->where('id', '>', 10000) ->update(['discord_id' => DB::raw('id')]); // 3. Temporary new auto increment column Schema::table('users', function (Blueprint $table) { $table->unsignedBigInteger('new_id')->first(); }); // 3.5 Count DB::statement(' UPDATE users u JOIN ( SELECT id, ROW_NUMBER() OVER (ORDER BY id) AS rn FROM users ) t ON u.id = t.id SET u.new_id = t.rn '); // 4. Drop foreign keys $this->dropForeignKeys(); // 5. Fix ID's in other tables $this->updateUserIDsInOtherTables(); // 6. Remove old ID Schema::table('users', function (Blueprint $table) { $table->bigInteger('id')->unsigned()->change(); $table->dropPrimary('id'); $table->dropColumn('id'); }); // 7. Rename new_id to id Schema::table('users', function (Blueprint $table) { $table->renameColumn('new_id', 'id'); }); // 8. Change new ID to auto increment and set as primary key Schema::table('users', function (Blueprint $table) { $table->unsignedBigInteger('id')->autoIncrement()->primary()->change(); }); // 9. Remove data that would conflict with constraints $this->deleteUnreferencedData(); // 9. Recreate foreign key constraints $this->addForeignKeys(); } /** * Drop Foreign Keys referencing the user id */ private function dropForeignKeys(): void { Schema::table('markable_likes', function (Blueprint $table) { $table->dropForeign(['user_id']); }); Schema::table('watched', function (Blueprint $table) { $table->dropForeign(['user_id']); }); // Our Schema does include a foreign key, for whatever reason it doesn't exist in the first palce // Schema::table('user_downloads', function (Blueprint $table) { // $table->dropForeign(['user_id']); // }); } /** * Tables to fix the IDs: * - comments ['commenter_id'] * - markable_likes ['user_id'] * - notifications ['notifiable_id'] * - playlists ['user_id'] * - user_downloads ['user_id'] * - watched ['user_id'] */ private function updateUserIDsInOtherTables(): void { DB::statement(' UPDATE comments c JOIN users u ON c.commenter_id = u.id SET c.commenter_id = u.new_id '); DB::statement(' UPDATE watched w JOIN users u ON w.user_id = u.id SET w.user_id = u.new_id '); DB::statement(' UPDATE markable_likes ml JOIN users u ON ml.user_id = u.id SET ml.user_id = u.new_id '); DB::statement(' UPDATE notifications n JOIN users u ON n.notifiable_id = u.id SET n.notifiable_id = u.new_id '); DB::statement(' UPDATE playlists p JOIN users u ON p.user_id = u.id SET p.user_id = u.new_id '); DB::statement(' UPDATE user_downloads ud JOIN users u ON ud.user_id = u.id SET ud.user_id = u.new_id '); } /** * Due to incorrect handling of user deletes, * we have unreferenced data */ private function deleteUnreferencedData(): void { // User Downloads Table DB::table('user_downloads') ->where('user_id', '>', 1_000_000) ->delete(); // User Playlists Table $playlists = Playlist::where('user_id', '>', 1_000_000) ->get(); foreach($playlists as $playlist) { DB::table('playlist_episodes') ->where('playlist_id', '=', $playlist->id) ->delete(); $playlist->delete(); } } /** * Re-Add Foreign Keys to tables which we dropped previously */ private function addForeignKeys(): void { Schema::table('markable_likes', function (Blueprint $table) { // Ensure the column is unsigned $table->bigInteger('user_id')->unsigned()->change(); // Add the foreign key constraint $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); }); Schema::table('watched', function (Blueprint $table) { // Ensure the column is unsigned $table->bigInteger('user_id')->unsigned()->change(); // Add the foreign key constraint $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); }); Schema::table('user_downloads', function (Blueprint $table) { // Ensure the column is unsigned $table->bigInteger('user_id')->unsigned()->change(); // Add the foreign key constraint $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); }); Schema::table('playlist_episodes', function (Blueprint $table) { // Ensure the column is unsigned $table->bigInteger('playlist_id')->unsigned()->change(); // Add the foreign key constraint $table->foreign('playlist_id')->references('id')->on('playlists')->onDelete('cascade'); }); Schema::table('playlists', function (Blueprint $table) { // Ensure the column is unsigned $table->bigInteger('user_id')->unsigned()->change(); // Add the foreign key constraint $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); }); } };