sql >> Databasteknik >  >> RDS >> Database

En SaaS-prenumerationsdatamodell

SaaS (Software as a Service) är en av de tre huvudkomponenterna i cloud computing. Vanligtvis är SaaS-applikationer webbaserade och kan hantera många olika användare samtidigt. Prenumerationsbaserade lösningar är mycket populära SaaS-erbjudanden. Några välkända SaaS-produkter inkluderar Microsoft Office 365, Amazon Web Services (AWS), Slack, Jira, Stripe och (naturligtvis) Vertabelo! Idag ska vi ta en titt på en datamodell som skulle tillåta oss att hantera SaaS-prenumerationer.

Idén

SaaS-produkter kan vara väldigt olika. Vissa tar regelbundet betalt för sina tjänster, t.ex. månadsvis eller årligen; andra tar bara betalt för mängden tid eller resurser som används (eller en kombination av dessa två). För att göra det enkelt i den här artikeln fokuserar jag bara på månadsbetalda prenumerationer.

Låt oss anta att vi har några olika SaaS-lösningar och att vi måste spåra alla våra prenumeranter i en databas. Detta kan vara fallet när vi tillhandahåller databaslösningar (t.ex. Amazon DynamoDB), analysverktyg (t.ex. Amazon Athena) eller robotapplikationer (t.ex. AWS RoboMaker). Faktum är att om vi tittar på Amazon kan vi se att det finns många olika applikationer tillgängliga. Vi skulle bara välja de vi verkligen behöver.

Datamodell




Modellen består av tre ämnesområden:

  • Users & groups
  • Software & plans
  • Subscriptions, plans & payments.

Vi kommer att beskriva vart och ett av dessa ämnesområden i den ordning de är listade.

Avsnitt 1:Användare och grupper

Users & groups ämnesområde lagrar information om alla användare av vår applikation. Vi antar att användare kan grupperas, t.ex. när ett företag vill köpa licenser för flera anställda. Vi skapar en grupp även när bara en användare tillhör den. Detta ger oss flexibiliteten att senare lägga till nya medlemmar i den gruppen.

Den viktigaste tabellen här är user_account tabell. Vi kommer att använda den för att lagra all information relaterade till användarkonton. Dessa är:

  • first_name & last_name – Användarens för- och efternamn. Observera att varje användare som lagras här är en privatperson.
  • user_name – Ett användarnamn (valt av användaren).
  • password – Ett hashvärde för användarens lösenord. (Användare ställer in sina egna lösenord.)
  • email – Användarens e-postadress, ställd under registreringsprocessen.
  • confirmation_code – Koden som användes under e-postbekräftelseprocessen.
  • confirmation_time – När registreringen/bekräftelsen var klar.
  • insert_ts – Tidsstämpeln när den här posten ursprungligen infogades.

Användare kan skapa grupper; grupper har fördefinierade typer. En lista över alla möjliga grupptyper lagras i user_group_type tabell. Varje typ definieras UNIKT av dess type_name . Vi kommer också att definiera det lägsta och högsta tillåtna antalet gruppmedlemmar för varje grupptyp. Det intervallet definieras med två värden – members_min (den nedre gränsen) och members_max (den övre gränsen).

När användarna skapar ett nytt konto väljer de också sin användargrupp. Detta skapar en ny post i user_group tabell som refererar till den valda grupptypen och lagrar tidsstämpeln (insert_ts ) när denna post infogades. customer_invoice_data attribut är en textbeskrivning av vad vi skriver ut på fakturan för den användargruppen.

Den sista tabellen i detta ämnesområde är in_group tabell. För varje grupp lagrar vi en lista över alla dess medlemmar. Förutom referenser till användargruppen (user_group_id ) och användarkonto (user_account_id ), lagrar vi även tidsstämpeln när en användare lades till i gruppen (time_added ) eller tagits bort från gruppen (time_removed , som bara kommer att innehålla ett värde om användaren har tagits bort). Vi kommer också att ha en flagga för att ange om användaren är group_admin eller inte. Gruppadministratörer kan uppdatera gruppmedlemmar och lägga till nya medlemmar.

Avsnitt 2:Programvara och planer

Därefter måste vi definiera allt vi kommer att erbjuda våra (potentiella) kunder. Vi kanske bara erbjuder en typ av programvara, men det finns en stor möjlighet att vi kommer att ha flera olika erbjudanden. Ett vanligt exempel på detta fall är att ha ett SaaS-verktyg som är skilt från dess analysapplikation, t.ex. Stripe och Stripe Sigma. Vi kommer att täcka sådana fall i vår datamodell.

Vi börjar med software tabell. I den här ordboken lagrar vi en lista över alla våra SaaS-erbjudanden. För var och en lagrar vi:

  • software_name – ETT UNIKT programvarunamn.
  • details – Alla detaljer som beskriver den programvaran.
  • access_link – En plats eller länk där vi kan komma åt den programvaran.

Vi ska kunna erbjuda våra SaaS-lösningar i en eller flera olika planer. Varje plan innehåller olika alternativ. Till exempel kan vi ha en premiumplan som inkluderar alla alternativ vi erbjuder och en grundläggande plan som bara inkluderar det väsentliga. Vi lagrar alla distinkta planer i plan tabell. För varje plan kommer vi att definiera:

  • plan_name – Namnet vi har valt för denna plan. Tillsammans med referensen till programvaran (software_id ), detta bildar den alternativa/UNIKA nyckeln för denna tabell.
  • user_group_type_id – En referens som anger vilken typ av grupp som kan använda denna plan. Detta kan vara en enanvändargrupp eller en standardgrupp. Denna referens definierar också det maximala antalet gruppmedlemmar för den planen – t.ex. om vår plan tillåter fem olika konton på en prenumeration bör vi referera till lämplig user_group_type .
  • current_price – Det aktuella priset för denna plan.
  • insert_ts – Tidsstämpeln när denna post infogades.
  • active – En flagga som anger om denna plan är aktiv eller inte.

Vi har redan nämnt att planer för samma programvara kommer med olika alternativ. En lista över alla distinkta alternativ lagras i option lexikon. Varje alternativ definieras UNIKT av dess option_name .

För att tilldela alternativ till olika planer använder vi option_included tabell. Den lagrar referenser till den relaterade planen (plan_id ) och alternativet (option_id ). Detta par, tillsammans med date_added attribut, bildar den UNIKA nyckeln för denna tabell. date_removed attribut kommer endast att innehålla ett värde om vi beslutat att ta bort ett visst alternativ från en plan. Detta kan hända när vi bygger ett nytt alternativ för att ersätta det gamla eller när vi beslutar att inte ha ett givet alternativ längre eftersom få människor använder det.

Den sista delen av detta ämnesområde är relaterad till special- eller kampanjerbjudanden. I allmänhet ger sådana erbjudanden kunderna mer service för mindre pengar och varar under en viss tid. De kan syfta till att skaffa nya kunder eller sälja planuppgraderingar (eller ett bredare utbud av tjänster) till befintliga kunder.

Alla våra kampanjerbjudanden lagras i offer tabell. För varje erbjudande måste vi definiera:

  • offer_name – ETT UNIKT namn som vi har valt för det här erbjudandet.
  • offer_start_date och offer_end_date – Den tidsperiod under vilken erbjudandet är tillgängligt.
  • description – En detaljerad textbeskrivning av erbjudandet.
  • Rabatter:Vi behöver flexibiliteten för att ha två typer av rabatter – en fast beloppsbaserad rabatt (t.ex. få $50 rabatt) och en procentuell rabatt (t.ex. spara 25%). Om vi ​​erbjuder en fast rabatt, infogar vi det värdet i discount_amount attribut; om vi erbjuder en procentuell rabatt kommer vi att infoga den procenten i discount_percentage attribut.
  • Varaktighet:Vi kommer att använda samma logik här som vi har använt för rabatterna. I vissa fall kommer erbjudanden att gälla i ett definierat antal månader (t.ex. i 24 månader efter att kunder har registrerat sig); i dessa fall kommer vi att definiera duration_months värde. Övriga erbjudanden kommer att gälla till ett visst fast datum (t.ex. till 31 december 2019); för dessa definierar vi datumet och lagrar det i duration_end_date attribut.

Vi kommer att använda de återstående två tabellerna i detta ämnesområde för att definiera vad varje erbjudande innehåller och vilka förutsättningar det har. För detta ändamål använder vi två tabeller:include och prerequisite . De delar samma struktur och innehåller samma UNIKA par av offer_idplan_id . Vissa erbjudanden kanske inte har några förutsättningar, medan andra kan – t.ex. om vi erbjuder en rabatt för att uppgradera till en plan med fler användare eller en mjukvaruprenumeration för användare av någon annan programvara.

Erbjudanden kan vara komplexa, så jag ska ge några exempel.

  1. Om vi ​​för närvarande använder plan A och har ett erbjudande om att uppgradera till plan B är detta enkelt.
  2. Om vi ​​har två erbjudanden, "Plan A uppgraderar till Plan B" och "Plan B uppgraderar till Plan C", bör vi skapa ytterligare ett erbjudande:"Plan A uppgraderar direkt till Plan C". Detta tillåter användare att uppgradera sina planer i ett steg snarare än två. Ett exempel på en sådan uppgradering är att ändra ett abonnemang som för närvarande tillåter fem användare per grupp till ett som tillåter 20 användare per grupp utan att stanna vid en mellanliggande plan med tio användare per grupp på vägen.
  3. Om en grupp använder produkt A kan vi ha ett specialerbjudande om att prenumerera på produkter B och C till ett kampanjpris. Vi kan också ha två separata erbjudanden om att prenumerera endast på produkt B och endast på produkt C.

I allmänhet bör vi ha ett erbjudande som kommer att ändra den nuvarande planen till den önskade planen utan några steg emellan och bara ett erbjudande om att prenumerera på en eller flera nya produkter.

Avsnitt 3:Prenumerationer, planer och betalningar

Det sista ämnesområdet förbinder de två tidigare nämnda områdena och är det sanna hjärtat i denna modell.

Alla prenumerationer lagras i subscription tabell. Vi kommer att behandla varje olika plan som en separat prenumeration, även om dessa prenumerationer/planer är resultatet av samma erbjudande. Anledningen till detta är att vi ska kunna hantera prenumerationer separat – t.ex. avbryta dem separat om vi ville. Vi måste definiera ett antal detaljer här:

  • user_group_id – ID för gruppen som prenumererar på denna plan. Detta är viktigt eftersom användare inte kommer att prenumerera individuellt; de tecknas indirekt, som en del av gruppen.
  • trial_period_start_date och trial_period_end_date – De nedre och övre gränserna för provperioden (om någon) för denna prenumeration.
  • subscribe_after_trial – En flagga som anger om prenumerationen kommer att förnyas automatiskt efter att provperioden (om någon) har slutat.
  • current_plan_id – Den nuvarande planen för den prenumerationen. Om prenumerationen inte längre är aktiv kommer detta attribut att innehålla värdet av den senast aktiva planen.
  • offer_id – En referens till erbjudandet som denna prenumeration är relaterad till. Det här attributet kommer endast att innehålla ett värde om denna prenumeration var resultatet av ett visst erbjudande.
  • offer_start_date och offer_end_date – Den nedre och övre gränsen för den period under vilken detta erbjudande var aktivt. Dessa attribut kommer endast att definieras om denna prenumeration var resultatet av ett visst erbjudande.
  • date_subscribed – När den här gruppen prenumererade på den här prenumerationen.
  • valid_to – Sista datum då denna prenumeration är giltig. I fallet med en månadsprenumeration kan vi förvänta oss att valid_to kommer att ställas in till slutet av innevarande månad. Om en kund avslutar prenumerationen när som helst under en månad, kommer de fortfarande att kunna använda sin programvara fram till slutet av den månaden.
  • date_unsubscribed – Datumet då gruppen avslutade prenumerationen från denna prenumeration. Vi kan förvänta oss att detta datum kommer att ställas in manuellt av gruppadministratören när gruppen bestämmer sig för att inte använda tjänsten längre. Den skulle dock också kunna ställas in automatiskt, enligt fördefinierade kriterier – t.ex. automatiskt avregistrera en grupp från deras tjänst om det finns två eller flera obetalda fakturor.
  • insert_ts – Tidsstämpeln när denna post infogades.

Prenumerationsplaner ändras ofta över tiden. För att upprätthålla en fullständig historik över alla våra planer lagrar vi alla planändringar i plan_history tabell. För varje post här behöver vi ett:

  • subscription_id – ID för den relaterade prenumerationen.
  • plan_id – ID för den relaterade planen.
  • date_start och date_end – Tidsperioden då denna plan var aktiv.
  • insert_ts – Tidsstämpeln när denna post infogades.

Den sista tabellen i vår modell lagrar våra invoices . För varje faktura behåller vi följande uppgifter:

  • customer_invoice_data – En beskrivning av kunden som fakturerats för denna faktura. Detta kommer att vara data från user_group.customer_invoice_data i det ögonblick då fakturan skapades.
  • subscription_id – ID för den relaterade prenumerationen.
  • plan_history_id – ID för planen som är aktiv under denna fakturaperiod.
  • invoice_period_start_date och invoice_period_end_date – Tidsintervallet (t.ex. 1 januari 2019 till 31 januari 2019) som täcks av denna faktura.
  • invoice_description – En kort textbeskrivning av fakturan.
  • invoice_amount – Betalningsbeloppet för denna faktura.
  • invoice_created_ts – När denna faktura genererades och infogades i tabellen.
  • invoice_due_ts – När denna faktura förfaller.
  • invoice_paid_ts – Tidsstämpeln när denna faktura betalades.

Berätta för oss vad du tycker om SaaS-datamodellen

Jag antar att de flesta av er har träffat SaaS, antingen som utvecklare eller som användare. Jag ser fram emot din syn på den och den här datamodellen. Dela gärna med dig av dina erfarenheter och förslag i kommentarerna nedan.


  1. MAX() vs GREATEST() i MySQL:Vad är skillnaden?

  2. JSON-funktioner och -operatörer i SQLite (fullständig lista)

  3. Hur ställer jag in sortering för en anslutning i SQL Server?

  4. Hur man använder OBJECT_ID() på korsdatabasobjekt i SQL Server