Tables and Columns

Creating Tables and Choosing Column Types

Schema::create() passes a Blueprint to a closure; each method call adds a column, and the driver's grammar turns it into DDL. This is MySQL's products table the Laravel 2,157 way:

The up() method of create_products_tablePHP
Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('sku', 20)->unique();
    $table->string('title', 200);
    $table->foreignId('category_id')->constrained();
    $table->decimal('price', 8, 2);
    $table->unsignedInteger('stock')->default(0);
    $table->json('attributes')->nullable();
    $table->timestamps();
});

Columns are NOT NULL unless you chain nullable(). string, char, decimal, enum, json and dateTime map one to one onto MySQL's types; SHOW CREATE TABLE showed these differences:

Blueprint methods and the MySQL 524 types they produced
Blueprint method MySQL type created MySQL choice
id() bigint unsigned auto-increment primary key INT UNSIGNED
foreignId('category_id') bigint unsigned SMALLINT UNSIGNED
string('sku', 20) varchar(20) COLLATE utf8mb4_unicode_ci VARCHAR(20), server collation
timestamps() two timestamp NULL columns created_at DATETIME only

Keys are BIGINT because foreignId() must match id() (Foreign Keys); pair increments() with unsignedInteger() for narrower keys. Eloquent fills the timestamps() columns (Keys and Timestamps), but TIMESTAMP ends in 2038 (Date and Time Types), so datetimes() is the safer choice. The collation comes from config/database.php, overriding the server's utf8mb4_0900_ai_ci; set DB_COLLATION to change it. Every new enum() value costs an ALTER TABLE, so for statuses that grow, prefer a string cast to a PHP enum (Casting).