(written by Grok and reviewed by Max Milbers)
Audience: Developers and shop builders working with child products and Multivariant
Related: Reduced database access by using booleans for reference tables
VirtueMart stays fast with large variant trees because two mechanisms work together: product property inheritance (child products only store what differs) and skipped reference loads when a relation is empty. Multivariant is that model on the storefront.
1. Short pointer: has_x reference tables
In Reduced database access by using booleans for reference tables we describe how main rows carry flags such as has_categories, has_medias, has_prices, has_manufacturers, has_shoppergroups. If the flag says there is nothing in that xref table, VirtueMart does not load it. “Do not query — there is nothing there.”
That alone cuts waste. With children it multiplies.
2. Product property inheritance (the multiplier)
A child is not a full copy of the parent. On getProduct(), empty fields on the child are filled from the parent chain. Category, long description, manufacturer text, shared defaults — usually live on the parent once.
The child row can stay almost empty. Only overrides are stored: another price, stock, SKU, dimensions, or a single media link.
Example: same shirt, three colours. Parent holds category, description, default gallery. Each child may only link a different image (has_medias true; categories on the child empty → no product_categories load for that child). Price xref loads only if the child has its own price.
So inheritance avoids duplicating columns; has_x avoids loading empty xrefs. Together: thin children × fewer JOINs = scalable variants.
3. Product patterns: unpublished parents are useful
A parent does not need to be a sellable catalogue item. You can use an unpublished product as a product pattern: the template that children inherit from, without the pattern itself appearing in the shop browse.
That is intentional. Sample data even names patterns this way (e.g. “PATTERN …”). Shoppers buy children (or Multivariant selections that resolve to children); the pattern stays backend structure — still one place to edit shared data for the whole family.
Extended Tutorial is here https://docs.virtuemart.net/tutorials/product-creation/product-with-child-variant-parent-not-ordable
4. Multivariant: inheritance on the product page
Multivariant puts the combination matrix in the UI: dropdowns for dimensions (size, length, weave, colour, …). Hundreds of sellable combinations stay one product screen. Selection resolves to a child product id — that child is still the sparse record above.
Same idea as in the database, applied to the frontend:
- Shared story and category context = parent / pattern.
- What changes per combination = child (price, image, stock, dimension fields).
- Empty relations on the child = not loaded (
has_x).
Multivariant is not “clever JS only”. On the page, a small dedicated script (e.g. cvfind) holds the combination matrix already rendered with the product. When the shopper changes a dropdown, the matching child is chosen client-side and resolved to that child’s real product URL — no extra “search me the right SKU” round trip to the PHP stack. The browser then loads that URL (full navigation or dynamic/AJAX content update, depending on configuration). Because each combination is a normal, addressable product URL, it is cacheable (browser, reverse proxy, Joomla/VM page cache). The server only serves a product it already knows how to cache; inheritance + has_x keep that product payload thin. That is the frontend half of the same sparse-data idea.
Extended Tutorial is here: https://docs.virtuemart.net/tutorials/product-creation/multivariant
5. Takeaway
| Layer | What you get |
|---|---|
has_x booleans |
Skip empty reference tables (see linked article) |
| Child inheritance | Store and load only overrides; parent holds the rest |
| Unpublished pattern parent | Shared template without a shop listing of the pattern itself |
| Multivariant | One UI matrix; each hit is still a thin child under the hood |
Related: Booleans for reference tables · Admin product edit: parent / children / Multivariant custom field