Jag har samma behov, och här är hur jag tacklade ditt aktierörelseproblem (som också blev mitt problem).
För att modellera lagerrörelser (+/-) har jag min supplying
och min order
tabeller. Leverans fungerar som mitt +lager, och mina beställningar mitt lager.
Om vi slutar med detta kan vi beräkna vårt faktiska lager som skulle transkriberas till denna SQL-fråga:
SELECT
id,
name,
sup.length - ord.length AS 'stock'
FROM
product
# Computes the number of items arrived
INNER JOIN (
SELECT
productId,
SUM(quantity) AS 'length'
FROM
supplying
WHERE
arrived IS TRUE
GROUP BY
productId
) AS sup ON sup.productId = product.id
# Computes the number of order
INNER JOIN (
SELECT
productId,
SUM(quantity) AS 'length'
FROM
product_order
GROUP BY
productId
) AS ord ON ord.productId = product.id
Vilket skulle ge något i stil med:
id name stock
=========================
1 ASUS Vivobook 3
2 HP Spectre 10
3 ASUS Zenbook 0
...
Även om detta kan spara dig en tabell, kommer du inte att kunna skala med den, därav det faktum att det mesta av modelleringen (imho) använder en mellanliggande stock
tabell, mest för prestationsproblem.
En av nackdelarna är datadupliceringen, eftersom du måste köra frågan ovan för att uppdatera ditt lager (se updatedAt
kolumn).
Den goda sidan är kundens prestation. Du kommer att leverera snabbare svar via ditt API.
Jag tror att en annan nackdel kan vara om du hanterar en butik med hög trafik. Du kan tänka dig att skapa en annan tabell som lagrar det faktum att ett lager håller på att beräknas om, och få användaren att vänta tills omräkningen är klar (push-förfrågan eller lång polling) för att kontrollera om var och en av hans/hennes artiklar fortfarande är tillgängliga (lager).>=användarbehov). Men det är en annan affär...
Hur som helst, även om frågan om beräkning av aktier använder anonyma underfrågor, borde den faktiskt vara ganska snabb nog i de flesta av de relativt medelstora butikerna.
Obs
Du ser i product_order
, jag duplicerade priset och momsen. Detta av tillförlitlighetsskäl:för att frysa priset vid köptillfället och för att kunna räkna om summan med många decimaler (utan att förlora cent i vägen).
Hoppas det hjälper någon som går förbi.
Redigera
I praktiken använder jag det med Laravel , och jag använder ett konsolkommando , som kommer att beräkna mitt produktlager i batch (jag använder också en valfri parameter för att bara beräkna för ett visst produkt-id), så mitt lager är alltid korrekt (i förhållande till frågan ovan), och jag uppdaterar aldrig lagertabellen manuellt.