sql >> Databasteknik >  >> RDS >> Database

Gillar du inte databasutlösare? Du vet bara inte hur man arbetar med dem!

När vi designar stora relationsdatabaser fattar vi ofta ett beslut att avvika från en normal form, dvs denormalisering.

Orsakerna till detta kan vara olika, såsom ett försök att snabba upp åtkomsten till specificerad data, begränsningar för den använda plattformen/ramverket/utvecklingsverktygen och bristande kompetens hos en databasutvecklare/designer.

Strängt taget är en hänvisning till rambegränsningar etc. faktiskt ett försök att motivera bristen på kompetens.

Den denormaliserade informationen är en sårbarhet, genom vilken det är lätt att föra vår databas till ett icke-konsistent (icke-integralt) tillstånd.

Vad kan vi göra med detta?

Exempel

I en databas finns en tabell med några finansiella operationer:mottagande och avyttring av medel på olika konton.

Vi behöver alltid veta saldot på kontot.

I de normaliserade uppgifterna är fondbehållningen alltid ett beräknat värde. Vi kommer att beräkna summan av kvitton utan debitering.

Det är dock för dyrt att beräkna saldot varje gång när det är många operationer. Därför beslöts att lagra det faktiska saldot i en separat tabell. Hur uppdaterar vi data i den här tabellen?

Lösningen är "som vanligt"

Nästan i alla informationssystem som jag var tvungen att arbeta med utfördes denna uppgift av en extern applikation, som implementerade affärslogiken. Du har tur om applikationen är enkel och det bara finns en dataändringspunkt, från formuläret i användargränssnittet. Men vad händer om det finns några importer, API:er, tredjepartsapplikationer etc. som utförs av olika personer och team? Vad händer om det finns flera tabeller med totalsummor istället för en? Vad händer om det finns mer än en tabell med operationer?

Det blir svårare att övervaka om en utvecklare uppdaterade ett gäng tabeller vid uppdatering av operationer. Datan förlorar integritet. Kontosaldot motsvarar inte verksamheten. Naturligtvis måste testning avslöja sådana situationer. Men vår värld är inte idealisk.

Triggers

Som ett alternativ används triggers för att kontrollera integriteten hos denormaliserade data.

Jag hörde att utlösare saktar ner en databas avsevärt, så det är meningslöst att använda dem.

Det andra argumentet var att all logik ligger i en separat applikation och att hålla affärslogik på olika ställen är orimligt.

Låt oss ta reda på det.

Fördröjningar

En utlösare aktiveras i transaktionen som ändrar data i tabellen. Transaktionen kan inte slutföras förrän utlösaren har utfört de nödvändiga stegen. Därför är slutsatsen att triggers måste vara 'light'.

Exemplet på den "tunga" frågan i utlösaren är följande:

update totals 
set total = select sum(operations.amount) from operations where operations.account = current_account
where totals.account = current_account

En fråga hänvisar till tabellen med operationer och summerar det totala beloppet av operationer för kontot .

När databasen ökar kommer en sådan fråga att förbruka mer och mer tid och resurser. Vi kan dock få samma resultat med den lätta frågan av följande typ:

update totals 
set total = totals.total + current_amount
where totals.account = current_account

När du lägger till en ny rad kommer denna utlösare helt enkelt att öka summan med kontot utan att beräkna den. Summan beror inte på datamängden i tabeller. Det är inte meningsfullt att beräkna summan igen, eftersom vi kan vara säkra på att utlösaren aktiveras varje gång när du lägger till en ny operation.

Att ta bort eller ändra rader bearbetas på samma sätt. Utlösare av denna typ kommer inte att sakta ner verksamheten, men kommer att säkerställa datakoppling och integritet.

Varje gång jag upplevde "lags" när jag lade till data till en tabell med en trigger, var det ett exempel på en sådan "tung" fråga. I de flesta fall var det möjligt att skriva om det i en "lätt" fråga.

Affärslogik

Vi måste skilja funktioner som tillhandahåller dataintegritet från affärslogiken. I varje fall ställer jag en fråga om datan var normaliserad, skulle vi behöva en sådan funktion? Om den är positiv är funktionen affärslogik. Om negativ är funktionen att tillhandahålla dataintegritet. Du kan slå in dessa funktioner i triggers.

Det finns dock en uppfattning om att det är lätt att implementera all affärslogik genom DBMS, som PostgreSQL eller Oracle.

Jag hoppas att den här artikeln kommer att hjälpa till att minska antalet buggar i ditt informationssystem.

Naturligtvis tror jag långt ifrån att allt som skrivs här är den ultimata sanningen. I det verkliga livet är naturligtvis allt mycket mer komplicerat. Därför måste du fatta ett beslut i varje specifikt fall. Använd ditt tekniska tänkande!

P.S.

  • I artikeln uppmärksammade jag den enda aspekten av att använda triggers som ett kraftfullt verktyg.
  • Det tillvägagångssätt som beskrivs i artikeln gör det möjligt att undvika index i Operations tabell, vilket i sin tur kan påskynda processen att lägga till data till denna tabell. Vid höga volymer kompenserar detta tillvägagångssätt enkelt den tid som spenderas på avtryckaren.
  • Det är viktigt att förstå vilka verktyg vi behöver använda till. I det här fallet slipper du många problem.

  1. Ansluter applikationer som körs på Linux till Amazon Relational Database Services (RDS) för SQL Server

  2. Varför tillåter inte Oracle SQL oss att använda kolumnalias i GROUP BY-satser?

  3. SQLcl för att överföra data från Oracle till PostgreSQL eller YugabyteDB 🅾🐘🚀

  4. 3 sätt att returnera en lista över SQL Server Agent-jobb (T-SQL)