sql >> Database teknologi >  >> RDS >> Sqlserver

Hvordan kan jeg beholde tblPurchase- og tblProductStock-bordet uden at falde. (Jeg skal beholde både bord og værdi permanent uden fald)

Indekseret visning

En helt ny løsning baseret på Indekserede visninger er muligt.

En indekseret visning er en visning, der har et klynget indeks på sig, og dataene er faktisk lagret på disken.

Som jeg forstår det, forsøger du at beholde en sum af køb pr. produktvare gemt i tblProduct . Jeg har antaget, at ItemCode er PK for tblProduct og det ItemName er også defineret der (Vi kan ikke bruge MAX). i en indekseret visning). Så vi kan definere en visning som denne:

CREATE VIEW dbo.vwTotalPurchases
WITH SCHEMABINDING  -- must be schema bound, we cannot change underlying columns after creation
AS
SELECT
   ItemCode,
   SUM(Quantity) QuantityPurchased,
   COUNT_BIG(*) CountPurchases  -- if we group, must have count also, so that rows can be maintained
FROM dbo.tblPurchase  -- must use two-part names
GROUP BY itemCode;
GO

Vi kan derefter oprette et klynget indeks på det for at bevare det på disken. SQL Server vil vedligeholde indekset, hver gang der sker en opdatering af basistabellen. Hvis der ikke er flere rækker i grupperingen (identificeret ved at antallet er 0), slettes rækken:

CREATE UNIQUE CLUSTERED INDEX PK_vwTotalPurchases ON dbo.vwTotalPurchases (ItemCode);
GO

Hvis vi nu vil forespørge på det, kan vi forlade denne visning på tblProducts (forlod deltage, fordi der muligvis ikke er nogen køb):

SELECT
    p.ItemCode,
    p.ItemName,
    ISNULL(tp.QuantityPurchased, 0) QuantityPurchased,
    ISNULL(tp.CountPurchases, 0) CountPurchases
FROM tblProducts p
LEFT JOIN vwTotalPurchases tp WITH (NOEXPAND) ON tp.ItemCode = p.ItemCode;

Vi kan også definere dette som en visning (ikke en indekseret, men en standardvisning), så definitionen kan bruges overalt.

Bemærkning om NOEXPAND :

Hvis du ikke er på SQL Server Enterprise eller Developer Edition, skal du bruge tippet WITH (NOEXPAND) for at tvinge det til at bruge indekset, ellers vil det forespørge på basis tblPurchase i stedet. Og selv i disse udgaver er det bedst at bruge NOEXPAND .

Se denne artikel af Paul White om dette.




  1. Postgresql-forespørgsel til at få n-niveau overordnet-barn-relation gemt i en enkelt tabel

  2. Opdeling af afgrænsede værdier i en SQL-kolonne i flere rækker

  3. DATEDIFF() vs DATEDIFF_BIG() i SQL Server:Hvad er forskellen?

  4. Dato- og tidsenheder i MySQL (fuld liste)