Le choix architectural fondamental : flat ou EAV ?
Avant d'écrire une ligne de SQL, vous devez trancher entre deux philosophies de modélisation pour votre table de spécifications produit.
Pattern EAV (Entity-Attribute-Value)
Le pattern EAV stocke chaque attribut comme une ligne :
ps_feature_value_lang
(id_feature_value, id_lang, value)
Avantages : flexibilité maximale, ajout d'attributs sans migration de schéma.
Inconvénients pour le grossiste food : jointures multiples pour reconstruire une fiche, impossibilité d'indexer efficacement sur la valeur normalisée, zéro typage (tout est VARCHAR), requêtes analytiques (« tous les produits Vietnam avec DLC > 90 jours ») deviennent des monstres SQL.
Pattern Flat (colonnes dédiées)
La table ps_ac_product_spec opte pour une colonne par dimension métier :
CREATE TABLE ps_ac_product_spec (
id_product INT UNSIGNED NOT NULL,
country_origin CHAR(2), -- ISO 3166-1 alpha-2
allergens_mask SMALLINT UNSIGNED DEFAULT 0, -- bitmask 14 bits
net_weight_g DECIMAL(10,3),
gross_weight_g DECIMAL(10,3),
rpc_qty SMALLINT UNSIGNED,
dlc_days SMALLINT UNSIGNED,
lot_ref VARCHAR(64),
pack_type ENUM('carton','palette','vrac','surgelé','frais'),
caliber_label VARCHAR(32),
PRIMARY KEY (id_product),
FOREIGN KEY (id_product) REFERENCES ps_product(id_product)
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Pourquoi le bitmask pour les allergènes
Les 14 allergènes UE INCO sont un ensemble fini et stable. Un bitmask SMALLINT (16 bits, 14 utilisés) permet :
- Détection par opération bit :
WHERE allergens_mask & 1 = 1(gluten présent) - Index efficace sur la colonne entière
- Zéro risque de valeur parasite : impossible d'écrire « GLUTEN » en majuscule ou « gluten (traces) »
La correspondance bit ↔ allergène est stockée dans votre dictionnaire technique (ps_ac_dictionary), pas dans le code.
Le pattern _extra : règle 13 exception légitime
Cette table respecte la convention ps_ac_{ps_entity}_extra : elle étend 1:1 une entité PS native (ps_product) avec des colonnes additionnelles. L'id_product est à la fois PRIMARY KEY et FOREIGN KEY. Pas de AUTO_INCREMENT, pas de polymorphisme.
Le module PS correspondant ac_productspec crée cette table via son sql/install.sql — jamais de CREATE TABLE sauvage hors module.