Chapter 15 · Semi-Structured and Polymorphic Data

Entity-Attribute-Value Models: Uses and Failure Modes

Analyze Entity-Attribute-Value models, identify legitimate use cases and common failure modes, and compare EAV with JSON, subtype tables, and metadata-driven schemas.

Beginner75–105 minutesEAV + anti-pattern analysisLast reviewed: August 2026

Learning outcomes

The Entity-Attribute-Value (EAV) model stores attributes as rows rather than columns. It can support highly dynamic metadata, but it often creates weak typing, difficult constraints, complex queries, and poor discoverability. EAV is neither always wrong nor a default solution for flexibility.

01

Understand the EAV row model.

02

Identify valid EAV niches.

03

Recognize typing, integrity, and query problems.

04

Compare EAV with JSON, subtype tables, and metadata-driven relational designs.

Basic EAV shape

model · example
EntityAttributeValue(  entity_id,  attribute_code,  value_text)

Instead of:

model · example
Part(  weight_kg,  max_pressure_bar,  color)

Example rows

model · example
entity  attribute          value101     weight_kg          4.2101     color              red102     max_pressure_bar   20102     manufacturer_code  ACME

Why EAV is attractive

  • new attributes require no table DDL;
  • different entity types can carry different attributes;
  • sparse data uses rows only when values exist;
  • metadata can drive forms dynamically.

The type problem

If every value is text:

model · example
"4.2""red""2026-08-10""true"

the database loses strong type semantics.

Typed EAV variants

model · example
value_textvalue_numbervalue_datevalue_boolean

can restore some typing, but now each row must use exactly one value column and queries become more complex.

Constraint problem

How do you express:

model · example
max_pressure_bar > 0serial_number UNIQUE per manufacturertemperature_c BETWEEN -50 AND 300

when attributes are rows with metadata-defined meaning?

Required attributes

A normal NOT NULL column enforces presence directly. In EAV, “every Pump requires max_pressure_bar” usually requires metadata plus cross-row validation.

Uniqueness

“Every Part has a unique SKU” is easy as a relational column and awkward if SKU is an EAV attribute.

Query complexity

Find Parts where color=red and weight>4:

model · example
JOIN EAV once for colorJOIN EAV again for weightfilter/cast both values

Simple predicates become self-joins or conditional aggregation.

EAV warning

Moving columns into rows makes schema evolution easy but often makes every query and constraint harder.

Index complexity

Indexes may need combinations such as:

model · example
(attribute_code, value_text)(attribute_code, value_number)

but data distributions differ wildly across attributes.

Statistics problem

Optimizer statistics on a generic value column mix unrelated domains. “red,” “blue,” dates, product codes, and names may share one storage column, reducing estimation quality.

Metadata table

model · example
AttributeDefinition(  attribute_code,  data_type,  required_flag,  unit_code,  validation_rule)

helps govern EAV but does not recreate all benefits of normal DDL automatically.

Legitimate EAV niches

  • user-defined custom fields;
  • very sparse scientific/clinical observations;
  • metadata repositories;
  • dynamic survey answers;
  • systems where attribute definitions are themselves primary business data.

Bad EAV use

Core stable attributes such as:

model · example
customer_idwork_order_numberstatus_codeopened_atsku

should not be moved into EAV merely to avoid migrations.

EAV versus JSON

AspectEAVJSON
Attribute-level rowsYesNo
Easy whole-object retrievalHarderEasy
Metadata-driven filteringPossiblePossible
Strong relational constraintsDifficultDifficult for nested fields
Sparse dynamic attributesGood nicheOften simpler

EAV versus subtype tables

If there are only a few known Part families with stable fields, subtype tables are often clearer:

model · example
PumpPart(part_id, max_pressure_bar, flow_rate)CablePart(part_id, conductor_count, gauge)

Hybrid approach

Keep stable core columns relational and allow only explicitly “custom” attributes in EAV or JSON:

model · example
Part core columnsPartCustomAttribute values

WorkshopHub decision

NeedRecommendation
Core Part identityNormal columns
10 stable Part subtypesSubtype tables
User-defined custom fieldsEAV/JSON candidate
Raw diagnostic documentJSON candidate
Compliance-critical attributesTyped relational fields

Practice: EAV or not?

Custom customer fields

Each tenant can define up to 20 custom Customer fields with different labels and types. Core Customer fields remain stable. Is EAV reasonable?

Review answer

Yes, this is a plausible EAV niche because the custom attributes are genuinely tenant-defined metadata. Keep core identity and common attributes relational, use typed custom values, validate against AttributeDefinition, and do not let custom fields replace core schema.

Summary and next lesson

EAV is appropriate when attributes themselves are dynamic business metadata, but it is costly for stable, constrained core data. JSON is often simpler for document-shaped flexibility; subtype tables are better for a small number of known variants. The final lesson combines these ideas into hybrid relational/document designs.

References

  • Bill Karwin, SQL Antipatterns.
  • Martin Fowler, writings on dynamic properties and metadata.
  • Database documentation on JSON and generated columns.

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only assets compatible with the Ethereum/ERC-20 network. Do not send TRC-20/TRON assets.