web-dev-qa-db-ja.com

laravelユーザーの削除で自動増分をリセットする方法は?

Laravel 4で自動インクリメント値をリセットする方法を見つけるのに苦労してきましたが、この機能はlaravel 4に埋め込まれていないようです今のところ、私はこのようにしました:

$user = User::find($user_id);

                if ($user)  {
                    if ($user->delete()){

                    DB::statement('ALTER TABLE users AUTO_INCREMENT = '.(count(User::all())+1).';');

                    echo json_encode('User Was Deleted Successfully..');
                    }   
            }

データベースからユーザーを削除するたびに、自動インクリメントポインターをすべてのユーザーの数+1に設定しました。

誰かがより良い解決策を持っている場合は私に知らせてください。

15
aimiliano

他の誰もが答えたように、行を削除するときにカウンターを戻す必要は実際にはありません。ただし、truncateであるテーブルすべてのテーブル行を削除するを使用して、カウンターをリセットできます。

Foreign Key Constraintsが適用されているテーブルをtruncateすることはできません(truncatedeleteと同じではありませんkeeping自動インクリメントカウンター中にすべての行を削除します)。

したがって、foreign key constrainsを使用している間、MySQLはforeign key constraintsが適用されているテーブルを切り捨てることを停止する可能性があります。

次の手順を実行して目的を達成できますが、データの整合性が損なわれる可能性があることに注意してください。私はテスト目的にのみ使用します。

  1. DatabaseSeederクラス(app/database/seeds/DatabaseSeeder.phpで利用可能)を次のように編集します。

    <?php
    class DatabaseSeeder extends Seeder {
        /**
        * Run the database seeds.
        *
        * @return void
        */
        public function run()
        {
            Eloquent::unguard();
    
            // Disable Foreign key check for this connection before running seeders
            DB::statement('SET FOREIGN_KEY_CHECKS=0;');
    
            $this->call('UserTableSeeder');
            // ...
    
            // FOREIGN_KEY_CHECKS is supposed to only apply to a single
            // connection and reset itself but I like to explicitly
            // undo what I've done for clarity
            DB::statement('SET FOREIGN_KEY_CHECKS=1;');
        }
    }
    
  2. これで、テーブルシーダークラス(この例ではUserTableSeederapp/database/seeds/UserTableSeeder.phpで作成する必要があります)は、次のように切り捨てテーブルを呼び出すことができます。

    <?php
    class UserTableSeeder extends Seeder {
    
        public function run()
        {
            // Truncate the table.
            DB::table('users')->truncate();
    
    
            // The auto-increment has been reset.
            // Now we can start adding users.
            User::create(
                array(
                    'email' => '[email protected]',
                    'password' => Hash::make('test')
                )
            );
        }
    }
    
28
Abhishek Saini
use Illuminate\Support\Facades\DB;

public function refreshDB()
{
    $max = DB::table('users')->max('id') + 1; 
    DB::statement("ALTER TABLE users AUTO_INCREMENT =  $max");
}

// Note: This solution is for resetting the auto_increment of the table without truncating the table itself 
3
Yamakenji

スマートかどうかはわかりませんが、これでテーブルがクリーンアップされます。

public function cleanup($table_name)
{       
    DB::statement("SET @count = 0;");
    DB::statement("UPDATE `$table_name` SET `$table_name`.`id` = @count:= @count + 1;");
    DB::statement("ALTER TABLE `$table_name` AUTO_INCREMENT = 1;");
}

MySQLはAUTO_INCREMENTをlast + 1に設定します
外部キーをON UPDATE CASCADEに設定した場合、子供は変更を認識し、更新をカスケードします。

これにはサーバー時間がかかり、見返りはほとんどありません。だからこそ、「時間を無駄にしないでください」という応答がたくさんあるのでしょうか。カウントには、最後のIDではなく-> count()を使用する必要があります。

また、ステートメントの実行中にユーザーが追加された場合のエラーを防ぐために、ステートメントをトランザクション内に含める必要があるかどうかもわかりません。

2
Joeri

PostgreSQLを使用している場合:

public function resetAutoincrement()
{
    $max = DB::table('users')->max('id') + 1;
    DB::statement('ALTER SEQUENCE users_id_seq RESTART WITH ' . $max);
}
0
pableiros