@@ -40,6 +40,76 @@ Schema::create('users', function (Blueprint $table) {
4040});
4141```
4242
43+ ## Schema Normalization
44+
45+ ### Motivation
46+
47+ Legacy database schemas often use ** composite primary keys** , which are ** not supported** by Laravel's Eloquent ORM.
48+ This can cause issues when working with relationships, factories, and model binding.
49+
50+ To address this, the migration generator offers an optional ** normalization step** that transforms composite primary
51+ keys into a ** synthetic, single-column primary key** .
52+
53+ ### How It Works
54+
55+ When the ` --normalizer=primary-key ` option is enabled:
56+
57+ 1 . ** Composite primary keys** are detected and removed.
58+ 2 . A synthetic ` $table->id() ` column is added as the new primary key.
59+ 3 . The original composite key is retained as a ** named unique constraint** :
60+ ``` php
61+ $table->unique(['user_id', 'role_id'], 'role_user_user_id_role_id_unique');
62+ ```
63+
64+ ### Example
65+
66+ ** Legacy schema:**
67+
68+ ``` sql
69+ CREATE TABLE role_user
70+ (
71+ user_id INT ,
72+ role_id INT ,
73+ PRIMARY KEY (user_id, role_id)
74+ );
75+ ```
76+
77+ ** Normalized Laravel migration:**
78+
79+ ``` php
80+ Schema::create('role_user', function (Blueprint $table) {
81+ $table->id(); // synthetic primary key
82+ $table->unsignedBigInteger('user_id');
83+ $table->unsignedBigInteger('role_id');
84+
85+ $table->unique(['user_id', 'role_id'], 'role_user_user_id_role_id_unique');
86+ // Original primary key: PRIMARY KEY (user_id, role_id)
87+ });
88+ ```
89+
90+ ### How to Enable
91+
92+ Use the CLI option during migration generation:
93+
94+ ``` bash
95+ php artisan migrate:regenerate --normalizer=primary-key
96+ ```
97+
98+ You can also enable it via the config file:
99+
100+ ``` php
101+ // config/migration-generator.php
102+ 'normalizer' => [
103+ 'enabled' => ['primary-key'],
104+ ],
105+ ```
106+
107+ ### Notes
108+
109+ - This feature is ** non-destructive** : the original uniqueness semantics are preserved.
110+ - Designed for compatibility with Laravel’s Eloquent, seeding, and testing tools.
111+ - Runs during the ** pre-generation transformation phase** , before compilation.
112+
43113## Dry-Run Mode (Planned)
44114
45115Coming soon: preview changes without writing files to disk.
0 commit comments