Skip to main content

Command Palette

Search for a command to run...

Entity-Attribute-Value (EAV) Pattern

Published
•2 min read•View as Markdown

The Entity-Attribute-Value (EAV) pattern is a data model used when you need to store flexible, schema-less data — especially when the number or types of attributes vary widely between records. In Laravel, this can be implemented using multiple related tables.


🔧 Typical EAV Structure in Laravel

You usually have three main tables:

  1. Entities – The main item (e.g., Product, User, etc.)

  2. Attributes – Defines the possible attributes (e.g., color, size, weight)

  3. Values – Stores the value of a specific attribute for a specific entity


🧱 Example: Product EAV

1. products table (Entities)

Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->timestamps();
});

2. attributes table

Schema::create('attributes', function (Blueprint $table) {
    $table->id();
    $table->string('name'); // e.g., "Color", "Size"
    $table->string('data_type'); // e.g., "string", "integer"
    $table->timestamps();
});

3. attribute_values table (Values)

Schema::create('attribute_values', function (Blueprint $table) {
    $table->id();
    $table->foreignId('product_id')->constrained('products')->onDelete('cascade');
    $table->foreignId('attribute_id')->constrained('attributes')->onDelete('cascade');
    $table->text('value'); // Store all values as string and cast later
    $table->timestamps();
});

🔁 Eloquent Models & Relationships

Product.php

public function attributes()
{
    return $this->hasMany(AttributeValue::class);
}

AttributeValue.php

public function product()
{
    return $this->belongsTo(Product::class);
}

public function attribute()
{
    return $this->belongsTo(Attribute::class);
}

Attribute.php

public function values()
{
    return $this->hasMany(AttributeValue::class);
}

✅ Pros

  • Flexible — easily add new attributes without changing schema

  • Useful for dynamic forms, CMSs, or products with varying specs


❌ Cons

  • Complex queries (especially filtering/sorting)

  • Performance issues on large data sets

  • Not ideal for frequently queried attributes


🧠 Tip

To reduce complexity and improve performance:

  • Cache commonly used attributes

  • Use JSON columns if EAV is overkill and you’re using MySQL 5.7+ or PostgreSQL