Level: Hard — A design-judgment question; picking the wrong storage model creates years of technical debt.
Scenario: You are designing a system that stores data with some fixed fields and some flexible/variable attributes. The interviewer asks: "Would you use a JSON column, normalized tables, or the EAV pattern? Give me a clear decision framework, not just a preference." This tests architectural maturity.
| Factor | Normalized | JSON Column | EAV |
|---|---|---|---|
| Schema flexibility | Low | High | Very high |
| Query performance | Excellent | Good (with generated cols) | Poor (join-hell) |
| Data integrity / types | Strong (FK, CHECK) | Weak | Very weak |
| Indexing | Native | Via generated columns | Awkward |
| Aggregation / reporting | Easy | Harder | Very hard |
| Best when attributes are | Known & stable | Flexible & sparse | Truly unbounded |
The senior recommendation — hybrid: Put frequently-queried, important fields in real columns (typed, indexed, constrained) and use a JSON column for the long tail of flexible/optional attributes. You get performance and integrity where it matters, and flexibility where it does not. On modern MySQL, this hybrid almost always beats pure EAV.
CREATE TABLE products (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
-- Hot, queried, important fields = real columns (indexed, typed)
name VARCHAR(255) NOT NULL,
price DECIMAL(10,2) NOT NULL,
category VARCHAR(50) NOT NULL,
in_stock BOOLEAN NOT NULL DEFAULT TRUE,
-- Long tail of flexible, per-category attributes = JSON
attributes JSON,
INDEX idx_category (category),
INDEX idx_price (price)
);
-- Promote ONE hot JSON path to an indexed generated column when needed
ALTER TABLE products
ADD COLUMN brand VARCHAR(50) AS (attributes->>'$.brand') VIRTUAL,
ADD INDEX idx_brand (brand);
-- Structured fields use fast native indexes:
SELECT * FROM products WHERE category = 'laptop' AND price < 60000;
-- Flexible attributes still available via JSON:
SELECT name FROM products WHERE attributes->>'$.color' = 'red';
Red flag — avoid pure EAV in a relational DB: Teams reach for EAV to "future-proof" schemas, then drown in self-joins and lose all type safety. If you genuinely need unbounded, document-shaped data, a document database (MongoDB) or a JSON column is almost always better than EAV in MySQL.
Interviewer follow-up: "The product team keeps adding new filterable attributes every sprint. JSON or normalized?" → If they must be filtered/faceted, neither pure approach scales gracefully in MySQL alone. Store the source of truth in the hybrid model, and push heavy faceted search to a dedicated engine like Elasticsearch. Match the tool to the access pattern instead of forcing everything into one table.