sql >> Database >  >> RDS >> Database

Een SaaS-abonnementsgegevensmodel

SaaS (Software as a Service) is een van de drie hoofdcomponenten van Cloud computing. Meestal zijn SaaS-applicaties webgebaseerd en kunnen ze veel verschillende gebruikers tegelijk aan. Op abonnementen gebaseerde oplossingen zijn zeer populaire SaaS-aanbiedingen. Enkele bekende SaaS-producten zijn Microsoft Office 365, Amazon Web Services (AWS), Slack, Jira, Stripe en (natuurlijk) Vertabelo! Vandaag bekijken we een datamodel waarmee we SaaS-abonnementen kunnen beheren.

Het idee

SaaS-producten kunnen heel verschillend zijn. Sommigen brengen regelmatig kosten in rekening voor hun diensten, b.v. maandelijks of jaarlijks; anderen rekenen alleen voor de hoeveelheid tijd of middelen die worden gebruikt (of een combinatie van deze twee). Om het in dit artikel eenvoudig te houden, richt ik me alleen op maandelijks betaalde abonnementen.

Laten we aannemen dat we een paar verschillende SaaS-oplossingen hebben en dat we al onze abonnees in één database moeten volgen. Dit kan het geval zijn wanneer we databaseoplossingen (bijv. Amazon DynamoDB), analysetools (bijv. Amazon Athena) of robottoepassingen (bijv. AWS RoboMaker) leveren. Als we naar Amazon kijken, kunnen we zien dat er veel verschillende applicaties beschikbaar zijn. We zouden alleen degene kiezen die we echt nodig hebben.

Gegevensmodel




Het model bestaat uit drie vakgebieden:

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

We zullen elk van deze onderwerpgebieden beschrijven in de volgorde waarin ze worden vermeld.

Sectie 1:Gebruikers en groepen

De Users & groups onderwerpgebied slaat informatie op over alle gebruikers van onze applicatie. We gaan ervan uit dat gebruikers kunnen worden gegroepeerd, b.v. wanneer een bedrijf licenties wil kopen voor meerdere werknemers. We maken een groep, zelfs als er maar één gebruiker bij hoort. Dit geeft ons de flexibiliteit om later nieuwe leden aan die groep toe te voegen.

De belangrijkste tabel hier is het user_account tafel. We zullen het gebruiken om alle details met betrekking tot gebruikersaccounts op te slaan. Dit zijn:

  • first_name & last_name – De voor- en achternaam van de gebruiker. Houd er rekening mee dat elke gebruiker die hier wordt opgeslagen een privépersoon is.
  • user_name – Een gebruikersnaam (gekozen door de gebruiker).
  • password – Een hash-waarde van het wachtwoord van de gebruiker. (Gebruikers stellen hun eigen wachtwoord in.)
  • email – Het e-mailadres van de gebruiker, ingesteld tijdens het registratieproces.
  • confirmation_code – De code die wordt gebruikt tijdens het bevestigingsproces per e-mail.
  • confirmation_time – Wanneer de registratie/bevestiging is voltooid.
  • insert_ts – Het tijdstempel waarop dit record voor het eerst werd ingevoegd.

Gebruikers kunnen groepen maken; groepen hebben vooraf gedefinieerde typen. Een lijst van alle mogelijke groepstypes wordt opgeslagen in de user_group_type tafel. Elk type wordt UNIEK gedefinieerd door zijn type_name . We bepalen ook het minimum en maximum aantal toegestane groepsleden voor elk groepstype. Dat bereik wordt gedefinieerd met twee waarden – members_min (de ondergrens) en members_max (de bovengrens).

Bij het aanmaken van een nieuw account zullen gebruikers ook hun gebruikersgroep selecteren. Dit zal een nieuwe record aanmaken in de user_group tabel die verwijst naar het geselecteerde groepstype en de tijdstempel opslaat (insert_ts ) toen deze record werd ingevoegd. De customer_invoice_data attribuut is een tekstuele beschrijving van wat we op de factuur voor die gebruikersgroep zullen afdrukken.

De laatste tabel in dit onderwerpgebied is de in_group tafel. Voor elke groep slaan we een lijst op met al zijn leden. Naast verwijzingen naar de gebruikersgroep (user_group_id ) en gebruikersaccount (user_account_id ), slaan we ook de tijdstempel op wanneer een gebruiker aan de groep werd toegevoegd (time_added ) of verwijderd uit de groep (time_removed , die alleen een waarde zal bevatten als de gebruiker is verwijderd). We hebben ook een vlag om aan te geven of de gebruiker de group_admin . is of niet. Groepsbeheerders kunnen groepsleden bijwerken en nieuwe leden toevoegen.

Sectie 2:Software en abonnementen

Vervolgens moeten we alles definiëren wat we onze (potentiële) klanten aanbieden. We bieden misschien maar één type software aan, maar de kans is groot dat we verschillende aanbiedingen hebben. Een veelvoorkomend voorbeeld van dit geval is het hebben van een SaaS-tool die los staat van de analysetoepassing, b.v. Streep en Streep Sigma. We zullen dergelijke gevallen behandelen in ons gegevensmodel.

We beginnen met de software tafel. In dit woordenboek slaan we een lijst op van al onze SaaS-aanbiedingen. Voor elk slaan we op:

  • software_name – EEN UNIEKE softwarenaam.
  • details – Alle details die die software beschrijven.
  • access_link – Een locatie of link waar we toegang hebben tot die software.

We moeten onze SaaS-oplossingen in één of meerdere verschillende abonnementen kunnen aanbieden. Elk plan bevat verschillende opties. We kunnen bijvoorbeeld een premium abonnement hebben dat alle opties omvat die we aanbieden en een basisabonnement dat alleen het essentiële bevat. We slaan alle afzonderlijke abonnementen op in het plan tafel. Voor elk plan definiëren we:

  • plan_name – De naam die we voor dit abonnement hebben gekozen. Samen met de verwijzing naar de software (software_id ), dit vormt de alternatieve/UNIEKE sleutel van deze tabel.
  • user_group_type_id – Een referentie die aangeeft welk type groep dit plan kan gebruiken. Dit kan een enkele gebruikersgroep zijn of een standaardgroep. Deze referentie definieert ook het maximale aantal groepsleden voor dat plan – b.v. als ons abonnement vijf verschillende accounts op één abonnement toestaat, moeten we verwijzen naar het juiste user_group_type .
  • current_price – De huidige prijs voor dit abonnement.
  • insert_ts – Het tijdstempel waarop dit record is ingevoegd.
  • active – Een vlag die aangeeft of dit plan actief is of niet.

We hebben al gezegd dat plannen voor dezelfde software verschillende opties zullen hebben. Een lijst met alle verschillende opties wordt opgeslagen in de option woordenboek. Elke optie is UNIEK gedefinieerd door zijn option_name .

Om opties aan verschillende abonnementen toe te wijzen, gebruiken we de option_included tafel. Het slaat verwijzingen op naar het gerelateerde abonnement (plan_id ) en optie (option_id ). Dit paar, samen met de date_added attribuut, vormt de UNIEKE sleutel van deze tabel. De date_removed attribuut zal alleen een waarde bevatten als we hebben besloten een bepaalde optie uit een abonnement te verwijderen. Dit kan gebeuren wanneer we een nieuwe optie bouwen om de oude te vervangen of we besluiten een bepaalde optie niet meer te hebben omdat maar weinig mensen deze gebruiken.

Het laatste deel van dit onderwerp heeft betrekking op speciale of promotionele aanbiedingen. Over het algemeen bieden dergelijke aanbiedingen klanten meer service voor minder geld en duren ze een bepaalde periode. Ze kunnen gericht zijn op het verwerven van nieuwe klanten of het verkopen van abonnementsupgrades (of een breder scala aan diensten) aan bestaande klanten.

Al onze aanbiedingen worden opgeslagen in de offer tafel. Voor elke aanbieding moeten we het volgende definiëren:

  • offer_name – Een UNIEKE naam die we hebben geselecteerd voor deze aanbieding.
  • offer_start_date en offer_end_date – De periode waarin deze aanbieding beschikbaar is.
  • description – Een gedetailleerde tekstuele beschrijving van het aanbod.
  • Kortingen:we hebben de flexibiliteit nodig om twee soorten kortingen te hebben:een korting op basis van een vast bedrag (bijvoorbeeld $ 50 korting) en een kortingspercentage (bijvoorbeeld 25% korting). Als we een vaste korting aanbieden, voegen we die waarde toe aan het discount_amount attribuut; als we een kortingspercentage aanbieden, voegen we dat percentage toe aan de discount_percentage attribuut.
  • Duur:we gebruiken hier dezelfde logica die we hebben gebruikt voor de kortingen. In sommige gevallen zijn aanbiedingen een bepaald aantal maanden geldig (bijvoorbeeld 24 maanden nadat klanten zich hebben aangemeld); in deze gevallen definiëren we de duration_months waarde. Andere aanbiedingen zijn geldig tot een bepaalde vaste datum (bijvoorbeeld tot 31 december 2019); hiervoor definiëren we de datum en slaan we deze op in de duration_end_date attribuut.

We gebruiken de resterende twee tabellen in dit onderwerpgebied om te definiëren wat elke aanbieding bevat en welke vereisten deze heeft. Voor dit doel gebruiken we twee tabellen:include en prerequisite . Ze delen dezelfde structuur en bevatten hetzelfde UNIEKE paar offer_idplan_id . Sommige aanbiedingen hebben mogelijk geen vereisten, terwijl andere - b.v. als we een korting aanbieden voor het upgraden naar een abonnement met meer gebruikers of een softwareabonnement voor gebruikers van andere software.

Aanbiedingen kunnen complex zijn, dus ik zal een paar voorbeelden geven.

  1. Als we momenteel Plan A gebruiken en een aanbieding hebben om te upgraden naar Plan B, is dit eenvoudig.
  2. Als we twee aanbiedingen hebben, "Plan A-upgrades naar Plan B" en "Plan B-upgrades naar Plan C", zouden we nog een aanbieding moeten maken:"Plan A-upgrades rechtstreeks naar Plan C". Hierdoor kunnen gebruikers hun abonnementen in één stap upgraden in plaats van in twee. Een voorbeeld van zo'n upgrade is het wijzigen van een abonnement dat momenteel vijf gebruikers per groep toestaat naar een abonnement met 20 gebruikers per groep zonder onderweg te stoppen bij een tussentijds abonnement van tien gebruikers per groep.
  3. Als een groep Product A gebruikt, kunnen we een speciale aanbieding hebben om zich voor een actieprijs op Producten B en C te abonneren. We kunnen ook twee afzonderlijke aanbiedingen hebben om alleen op Product B en alleen op Product C te abonneren.

Over het algemeen zouden we één aanbieding moeten hebben die het huidige plan in het gewenste plan zal veranderen zonder tussenliggende stappen en slechts één aanbieding om u te abonneren op een of meer nieuwe producten.

Sectie 3:Abonnementen, abonnementen en betalingen

Het laatste onderwerpgebied verbindt de twee eerder genoemde gebieden en is het ware hart van dit model.

Alle abonnementen worden opgeslagen in het plan tafel. We behandelen elk verschillend abonnement als een afzonderlijk abonnement, zelfs als deze abonnementen/abonnementen het resultaat zijn van dezelfde aanbieding. De reden hiervoor is dat we abonnementen afzonderlijk kunnen beheren - b.v. annuleer ze afzonderlijk als we dat wilden. We moeten hier een aantal details definiëren:

  • user_group_id – De ID van de groep die zich abonneert op dit abonnement. Dit is belangrijk omdat gebruikers niet individueel worden geabonneerd; ze zijn indirect geabonneerd, als onderdeel van de groep.
  • trial_period_start_date en trial_period_end_date – De onder- en bovengrenzen van de proefperiode (indien van toepassing) voor dit abonnement.
  • subscribe_after_trial – Een vlag die aangeeft of het abonnement automatisch wordt verlengd nadat de proefperiode (indien van toepassing) is afgelopen.
  • current_plan_id – Het huidige abonnement voor dat abonnement. Als het abonnement niet langer actief is, bevat dit kenmerk de waarde van het laatste actieve abonnement.
  • offer_id – Een verwijzing naar het aanbod waarop dit abonnement betrekking heeft. Dit kenmerk bevat alleen een waarde als dit abonnement het resultaat was van een bepaalde aanbieding.
  • offer_start_date en offer_end_date – De onder- en bovengrens van de periode waarin dit aanbod actief was. Deze kenmerken worden alleen gedefinieerd als dit abonnement het resultaat was van een bepaalde aanbieding.
  • date_subscribed – Wanneer deze groep zich op dit abonnement heeft geabonneerd.
  • valid_to – De laatste datum waarop dit abonnement geldig is. In het geval van een maandelijks abonnement kunnen we verwachten dat valid_to wordt ingesteld op het einde van de huidige maand. Als een klant zich op enig moment gedurende een maand uitschrijft, kan hij zijn software nog tot het einde van die maand gebruiken.
  • date_unsubscribed – De datum waarop die groep zich heeft afgemeld voor dit abonnement. We kunnen verwachten dat deze datum handmatig wordt ingesteld door de groepsbeheerder wanneer de groep besluit de service niet meer te gebruiken. Het kan echter ook automatisch worden ingesteld op basis van vooraf gedefinieerde criteria – b.v. automatisch een groep uitschrijven van hun service als er twee of meer onbetaalde facturen zijn.
  • insert_ts – Het tijdstempel waarop dit record is ingevoegd.

Abonnementen veranderen vaak in de loop van de tijd. Om een ​​volledige geschiedenis van al onze plannen bij te houden, slaan we alle planwijzigingen op in de plan_history tafel. Voor elke record hier hebben we een:

  • subscription_id – De ID van het gerelateerde abonnement.
  • plan_id – De ID van het gerelateerde abonnement.
  • date_start en date_end – De periode waarin dit plan actief was.
  • insert_ts – Het tijdstempel waarop dit record is ingevoegd.

In de laatste tabel in ons model worden onze invoices . Voor elke factuur bewaren we de volgende gegevens:

  • customer_invoice_data – Een beschrijving van de klant die voor deze factuur is gefactureerd. Dit zijn de gegevens van user_group.customer_invoice_data op het moment dat de factuur werd gegenereerd.
  • subscription_id – De ID van het gerelateerde abonnement.
  • plan_history_id – De ID van het abonnement dat actief is tijdens deze factuurperiode.
  • invoice_period_start_date en invoice_period_end_date – Het tijdsinterval (bijv. 1 januari 2019 tot 31 januari 2019) waarop deze factuur betrekking heeft.
  • invoice_description – Een korte tekstuele beschrijving van de factuur.
  • invoice_amount – Het verschuldigde bedrag voor deze factuur.
  • invoice_created_ts – Wanneer deze factuur is gegenereerd en in de tabel is ingevoegd.
  • invoice_due_ts – Wanneer deze factuur verschuldigd is.
  • invoice_paid_ts – Het tijdstempel waarop deze factuur is betaald.

Vertel ons wat u denkt over het SaaS-gegevensmodel

Ik denk dat de meesten van jullie SaaS hebben ontmoet, als ontwikkelaar of als gebruiker. Ik ben benieuwd naar jouw kijk erop en op dit datamodel. Deel gerust uw ervaringen en suggesties in de onderstaande opmerkingen.


  1. Volgorde van uitvoering van de SQL-query

  2. TSQL Try / Catch binnen Transactie of vice versa?

  3. PRINT-instructie in T-SQL

  4. MySQL:Snel overzicht van de soorten joins