bigIncrements('id'); // your users.id is char(26) $table->char('user_id', 26); $table->string('label', 100)->nullable(); // "Home", "Office" $table->string('kind', 20)->nullable(); // "billing", "shipping", "home", "work" // raw, user-entered fields $table->string('line1', 255)->nullable(); $table->string('line2', 255)->nullable(); $table->string('city', 100)->nullable(); $table->string('state', 64)->nullable(); $table->string('postal', 32)->nullable(); $table->string('country', 64)->nullable(); $table->string('phone', 32)->nullable(); // optional normalized location $table->unsignedBigInteger('location_id')->nullable(); // nullable so unique index allows many NULLs (only 1 with value 1) $table->boolean('is_primary')->nullable()->default(null); $table->timestamps(); // helpful indexes $table->index(['user_id', 'kind']); $table->index('postal'); $table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete(); $table->foreign('location_id')->references('id')->on('locations')->nullOnDelete(); // enforce at most one primary per (user,kind) $table->unique(['user_id', 'kind', 'is_primary'], 'user_kind_primary_unique'); }); /** * 2) lightweight geocoder bias on users (postal/country + optional centroid). */ Schema::table('users', function (Blueprint $table) { $table->string('postal', 32)->nullable()->after('timezone'); $table->string('country', 64)->nullable()->after('postal'); $table->decimal('lat', 9, 6)->nullable()->after('country'); $table->decimal('lon', 9, 6)->nullable()->after('lat'); $table->index('postal'); }); } public function down(): void { Schema::table('users', function (Blueprint $table) { if (Schema::hasColumn('users', 'postal')) $table->dropIndex(['postal']); foreach (['postal','country','lat','lon'] as $col) { if (Schema::hasColumn('users', $col)) $table->dropColumn($col); } }); Schema::table('user_addresses', function (Blueprint $table) { if (Schema::hasColumn('user_addresses', 'user_id')) $table->dropForeign(['user_id']); if (Schema::hasColumn('user_addresses', 'location_id')) $table->dropForeign(['location_id']); }); Schema::dropIfExists('user_addresses'); } };