Mam tę samą potrzebę, a oto, jak poradziłem sobie z twoim problemem związanym z ruchem giełdowym (który również stał się moim problemem).
W celu modelowania ruchu magazynowego (+/-), mam swoje supplying
i moje order
tabele. Zaopatrzenie działa jako moje +zapasy, a moje zamówienia jako -zapasy.
Gdybyśmy się na tym zatrzymali, moglibyśmy obliczyć nasze rzeczywiste zapasy, które zostałyby przeniesione na to zapytanie SQL:
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
Co dałoby coś takiego:
id name stock
=========================
1 ASUS Vivobook 3
2 HP Spectre 10
3 ASUS Zenbook 0
...
Chociaż może to zaoszczędzić ci jedną tabelę, nie będziesz w stanie skalować z nią, stąd fakt, że większość modelowania (imho) używa pośredniego stock
tabeli, głównie ze względów wydajnościowych.
Jedną z wad jest duplikacja danych, ponieważ będziesz musiał ponownie uruchomić powyższe zapytanie, aby zaktualizować swoje akcje (zobacz updatedAt
kolumna).
Dobrą stroną jest wydajność klienta. Będziesz dostarczać szybsze odpowiedzi za pośrednictwem swojego interfejsu API.
Myślę, że kolejną wadą może być zarządzanie sklepem o dużym natężeniu ruchu. Można sobie wyobrazić utworzenie kolejnej tabeli, która przechowuje fakt przeliczania zapasów i każe użytkownikowi czekać na zakończenie przeliczania (żądanie push lub długie odpytywanie) w celu sprawdzenia, czy wszystkie jego pozycje są nadal dostępne (zapasy>=żądanie użytkownika). Ale to już inna sprawa...
W każdym razie, nawet jeśli zapytanie o przeliczenie zapasów korzysta z anonimowych podzapytań, powinno być wystarczająco szybkie w większości stosunkowo średnich sklepów.
Uwaga
Widzisz w product_order
, powieliłem cenę i kadź. Dzieje się tak ze względu na niezawodność:zamrożenie ceny w momencie zakupu i możliwość przeliczenia sumy z dużą ilością miejsc po przecinku (bez utraty centów).
Mam nadzieję, że pomoże to komuś przechodzącemu.
Edytuj
W praktyce używam go z Laravel i używam polecenia konsoli , który obliczy moje zapasy produktów w partii (używam również opcjonalnego parametru do obliczenia tylko dla określonego identyfikatora produktu), więc moje zapasy są zawsze poprawne (w odniesieniu do zapytania powyżej) i nigdy nie aktualizuję ręcznie tabeli zapasów.