Laravel Database Field Types Reference

A Laravel database field types reference for migration column types and modifiers in the Schema builder.

Defining a migration

See the Artisan commands guide for more on make: generators like the one below.

php artisan make:migration create_posts_table
Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained()->cascadeOnDelete();
    $table->string('title');
    $table->text('body');
    $table->boolean('published')->default(false);
    $table->timestamps();
});

php artisan migrate

Common column types

MethodSQL type / purpose
id()Auto-incrementing BIGINT UNSIGNED primary key named id.
foreignId('user_id')BIGINT UNSIGNED sized to match id(), for foreign keys.
string('name', 255)VARCHAR, default length 255.
text('body')TEXT — longer, unbounded content.
longText('content')LONGTEXT for very large content.
integer('votes')Standard signed INT.
unsignedInteger('votes')Unsigned INT — no negative values.
bigInteger('views')Signed BIGINT.
tinyInteger('flag')Small integer, often used for compact enums/flags.
boolean('active')TINYINT(1), cast to PHP bool.
decimal('price', 8, 2)Fixed-precision decimal — use for money, never float.
float('rating', 8, 2) / double(...)Floating-point numbers — approximate, avoid for currency.
date('published_on')Date only, no time component.
dateTime('published_at')Date and time, no timezone awareness.
timestamp('verified_at')Like dateTime, but with timezone-related database behaviour.
timestamps()Adds nullable created_at and updated_at timestamp columns.
softDeletes()Adds a nullable deleted_at column for the SoftDeletes trait.
json('metadata')Native JSON column, pairs with an Eloquent array/object cast (inspect one with the JSON viewer).
uuid('external_id')CHAR(36) for storing a UUID string (generate one with the UUID generator).
enum('status', [...])Restricts the column to a fixed list of string values.
foreignIdFor(Model::class)Adds a foreign key column named after the given model.
morphs('commentable')Adds commentable_id + commentable_type for an Eloquent polymorphic relationship.
nullableMorphs(...) / ulidMorphs(...)Same as morphs(), but nullable, or using a ULID instead of a numeric ID.

Two related helpers don't add a normal column at all: storedAs('price * qty') (or virtualAs(...)) defines a generated column computed from other columns by the database itself, and $table->fullText('body') adds a full-text index for whereFullText() search queries.

Column modifiers

Chain these onto most column definitions to adjust their behaviour:

ModifierEffect
nullable()Allows NULL to be stored (columns are NOT NULL by default).
default($value)Sets a default value used when none is provided on insert.
unsigned()Disallows negative values on numeric columns.
unique()Adds a unique index on the column.
index()Adds a plain (non-unique) index for faster lookups.
$table->unique(['a', 'b'])Composite unique constraint across multiple columns — called on the table, not chained onto one column.
$table->index(['a', 'b'])Composite (multi-column) index, same call style as above.
comment('...')Attaches a comment to the column in the database schema.
after('column')Positions the column after another (MySQL only).
useCurrent()Defaults a timestamp column to CURRENT_TIMESTAMP.

Foreign keys

$table->foreignId('user_id')
    ->constrained()          // references users.id by convention
    ->cascadeOnDelete();     // or ->nullOnDelete(), ->restrictOnDelete()

// Explicit form
$table->foreign('user_id')
    ->references('id')->on('users')
    ->onDelete('cascade');

Modifying an existing table

Schema::table('posts', function (Blueprint $table) {
    $table->string('slug')->after('title')->nullable();
});

// Requires doctrine/dbal on older Laravel versions; built in on recent ones
Schema::table('posts', function (Blueprint $table) {
    $table->renameColumn('body', 'content');
});

// Dropping things — the counterpart to adding them above
Schema::table('posts', function (Blueprint $table) {
    $table->dropColumn('slug');
    $table->dropForeign(['user_id']);   // or ->dropForeign('posts_user_id_foreign')
    $table->dropIndex(['title']);
    $table->dropUnique(['email']);
});

Newer migrations are commonly generated without a wrapping class name at all — an anonymous class returned directly from the file, which is now the default from make:migration and avoids class name collisions between two migrations that both touch, say, a posts table. Passing --create=posts or --table=posts to make:migration pre-fills the Schema::create/Schema::table boilerplate shown throughout this page, based on naming convention alone (create_posts_table is detected as a create migration automatically).