Hoe scheidt SaaS bedrijf data van klanten

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Mark Hogeveen

Mark Hogeveen

15/11/2022 22:26:04
Quote Anchor link
Stel je voor je bent een softwarebedrijf dat SaaS (Software as a Service) diensten aanbiedt.
Bijvoorbeeld een online boekhoudsysteem, online reserveringssysteem, etc.
Zo'n bedrijf heeft meerdere klanten, dus de partijen die een dienst afnemen (meestal bedrijven).

Ik ga even uit van een standaard situatie bij een PHP applicatie.
Typisch gezien hebben de applicaties een bijbehorende database, met daarin database tabellen.

Als we een normale applicatie ontwikkelen zoals bijvoorbeeld PHPHulp, dan wordt onderscheid tussen data gemaakt met bijvoorbeeld user id's. Daar mee wil ik zeggen, de gegevens staan in een database en de gegevens worden 'gescheiden' (of juist gekoppeld) door relaties. Bijvoorbeeld een forum post heeft een topic_id, een post heeft een user_id, enz.

Bij een SaaS applicatie is dit wat complexer. Het hoogste niveau van scheiden van gegevens is het klantniveau van de dienst.
Met andere woorden, een bedrijf (klant) maakt gebruik van het online boekhoudprogramma. Alle gegevens in de applicatie moeten worden geassocieerd met die afnemer van de dienst. In dat bedrijf zitten weer medewerkers/gebruikers, wat de volgende scheiding is, en daarna heb je nog veel meer relaties.
Je zou dus kunnen zeggen dat als je één database hebt voor die hele SaaS applicatie, dat hierin gegevens van alle SaaS klanten tegelijkertijd in zitten.
In theorie zou dit prima kunnen. Maar mocht er ooit iets gebeuren (een nog niet ontdekte bug door een nieuwe feature), dan kan het zomaar zijn dat gegevens van verschillende SaaS klanten door elkaar komen. (Een afnemer van een reserveringssysteem ziet ineens reserveringen van een totaal ander bedrijf)

Het lijkt me ook meer gedoe in het ontwikkelen, want letterlijk bij elke query naar de database moet je iets doen als company_id = 1234. Als je dit in één query zou vergeten, heb je al een vet probleem.
Daarnaast wordt ook toegangscontrole/rechten meer werk om te implementeren, want een request met een id van een stuk data, kan wel elk id bevatten. Je moet controleren of dat stukje data bij de SaaS afnemer hoort, en dan gaat het pas verder met de rest. Dus de eigenlijke business logic van de applicatie.

Wordt dit opgelost door letterlijk een hele kopie van de applicatie te draaien voor elke afnemer van de dienst?
Dit lijkt me dan weer erg duur. De applicatie software (PHP code) is in principe voor iedereen hetzelfde, en zou dus misschien wel duizenden keren precies gedupliceerd worden op de server(s).
Of wordt voor elke afnemer een aparte database gemaakt?

Hoe werkt dit?
Gewijzigd op 15/11/2022 22:34:26 door Mark Hogeveen
 
PHP hulp

PHP hulp

21/11/2024 15:53:25
 
Adoptive Solution

Adoptive Solution

15/11/2022 22:45:35
Quote Anchor link
Ik kom een hele trits vragen en antwoorden tegen als ik zoek :
https://duckduckgo.com/?q=a+separate+database+for+every+customer
 
Ozzie PHP

Ozzie PHP

15/11/2022 23:34:49
Quote Anchor link
>> Het lijkt me ook meer gedoe in het ontwikkelen, want letterlijk bij elke query naar de database moet je iets doen als company_id = 1234.

Daarvoor is goed automatiseren een kunst. Je zou bijv. iets kunnen ontwikkelen dat een query uitvoert en altijd die company_id automatisch toevoegt, zodat je dat niet zelf hoeft te doen.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<?php

$sql
= 'SELECT name FROM company_info';
$db->query($sql);

?>

en in die query() functie gebeurt dan zoiets:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<?php

$sql
= $sql . ' WHERE company_id=' . $company->getId();
execute_query($sql);

?>

Het gaat er even niet om of dit kloppend is. Het gaat puur om het idee. Op het moment dat een klant inlogt, kun je kijken bij welk bedrijf hij hoort en dat ergens opslaan. En op het moment dat je een query uitvoert, kun je dan geautomatiseerd de company_id ophalen.
 

16/11/2022 08:48:01
Quote Anchor link
Je ontkomt er niet aan, je moet op een bepaald moment data scheiden.
De verschillende strategieën in oplopende gradatie van veiligheid:

1. Je voegt een klant ID toe aan elke tabel, en je neemt dit mee in al je queries
2. Je voegt een klant ID toe aan elke tabel en je regel autorisatie in de database
3. Je maakt per klant een schema in de database
4. Je maakt per klant een eigen database
5. Je maakt per klant een eigen database cluster (service)
6. Je maakt per klant een eigen database server

Optie 1 is veel werk en foutgevoelig.
Optie 2 is minder werk, maar nog steeds foutgevoelig wanneer Functioneel Beheer het fout doet.
Optie 3 is al beter, deze kom je vaak tegen bij shared hosting. Alles zit dan wel in dezelfde database, dus bij bugs of iets dergelijks hang je.
Optie 4 is als optie 3, maar het hangt er vanaf of je MySQL/MariaDB gebruikt of een betere database als PostgreSQL. PostgreSQL maakt naast schema's nog een onderscheid in databases, MySQL/MariaDB kan dat niet.
Optie 5 is nog beter, omdat daarmee data-autorisaties en databases volledig gescheiden zijn in aparte services, met elk een eigen poortnummer. Als dan 1 cluster er uit klapt (te weinig schijfruimte, hangende transactie, of MySQL die vastloopt op ZFS, etc.) dan hebben andere klanten daar geen last van.
Optie 6 is de beste. Het is als optie 5 maar dan met meerdere (virtuele) machines. Door de databases van meerdere klanten te spreiden over meerdere machines hebben ze geen last van elkaar qua performance, en is er meer keuze in software en bestandssystemen. Het andere belangrijke voordeel is dat ze via netwerk gescheiden zijn, waardoor er meer veiligheid kan worden ingebouwd door verkeer te filteren en te monitoren.

Wat betreft de PHP-applicatie; die zet je op een (liefst gescheiden) applicatie-server voor een 2-tier applicatie. Je kunt dan per URL een andere database laten selecteren.
Verdere performance kan worden behaald met een proxy-server voor SSL-offloading, en wanneer de applicatieserver vol loopt is het nodig om meerdere applicatieservers te hebben. Dat kan je doen per klant of aantal klanten, of je zet meerdere applicaties in een pool met load balancing.

En mocht een applicatie kritiek zijn en een hoge beschikbaarheid te hebben, dan moeten idealiter zowel de database servers als de webserver en load balancer uitgevoerd met High Availability (HA). Bijvoorbeeld PostgreSQL ondersteunt dit vanuit 'streaming replication', je hebt dan een reserve database server die synchroon loopt met de 'master', en als er één uitvalt heb je nog een andere database server met dezelfde data.
Overigens moeten dan gegevens altijd redundant worden opgeslagen in een RAID configuratie groter dan 1 (geen JBOD), als er dan een keer een harde schijf stuk gaat blijft het syteem gewoon doorlopen. Je kunt harde schijven 'hot swappable' uit een NAS of SAN trekken en er nieuwe in zetten, dan blijft het systeem gewoon door draaien. Dit laatste punt is overigens iets wat een hostingpartij standaard aan zou moeten bieden, dat hoef je niet zelf te doen als je het in de cloud op slaat. Maar met een private cloud, die je zelf beheert, is dat wel van belang.
Gewijzigd op 16/11/2022 09:09:35 door
 
Ward van der Put
Moderator

Ward van der Put

16/11/2022 09:57:28
Quote Anchor link
Het probleem van rollen en rechten moet je ook voor één organisatie vaak al oplossen. In een ziekenhuis heeft bijvoorbeeld lang niet iedere medewerker toegang tot het patiëntdossier van alle patiënten en in een verkooporganisatie heeft niet elke werknemer toegang tot de persoonsgegevens van alle klanten.

Als je dit voor één organisatie hebt opgelost, wordt het doorgaans makkelijker om het voor meerdere organisaties door te voeren. Afdelingen of functiegroepen kun je namelijk zien als organisaties binnen een organisatie.

Onder grootschalige SaaS-oplossingen zijn microservices populair. Daarbij heb je niet meer één monoliet-database voor alles en iedereen, maar is elke microservice (onder ideale omstandigheden) een self-contained system met volledig autonome code en zelfstandige opslag.
 

19/11/2022 10:57:26
Quote Anchor link
@Ward, klopt helemaal. Ik kom nu in de situatie dat een organisatie meerdere dochterorganisaties heeft, toch alles in 1 database wil (argument: onderhoud), met gescheiden functioneel beheer.
Ik ben altijd voorstander geweest van autorisaties op de data, maar met het scheiden van FB (een per dochterorganisatie, en centraal FB voor de moederorganisatie en kleinere dochterorganisaties) lijkt er meer nodig dan PostgreSQL autorisaties.
Je moet idealiter FB kunnen delegeren naar de lagere regionen die het voor zichzelf mogen inregelen.

Wat zijn mogelijke oplossingen voor dit vraagstuk? PostgreSQL is daarbij een onveranderlijk gegeven.
Gewijzigd op 19/11/2022 10:58:49 door
 
Mark Hogeveen

Mark Hogeveen

21/11/2022 20:35:31
Quote Anchor link
Een gedeelde database waarin alleen het onderscheid afhangt van een (WHERE) clausule in elke query is me te riskant.
Bovendien vraag ik me af of het ophalen / schrijven van data niet onnodig trager wordt als je één database hebt waar álle klanten hun gegevens in staan, eigenlijk ook nog eens van alle klanten door elkaar.
Om dit goed te doen, besef ik me nu dat er dus wel wat bij komt kijken. Je zou eigenlijk een soort virtuele server / VM moeten hebben voor elke klant, tenminste dat lijkt me een betere oplossing. Dankjewel voor de reacties.
Gewijzigd op 21/11/2022 20:38:56 door Mark Hogeveen
 
Ozzie PHP

Ozzie PHP

21/11/2022 21:00:32
Quote Anchor link
Het is uiteraard een afweging. Alles in 1 database: als er iets ontploft, ontploft het voor alle klanten. Alles in aparte databases: als 1 database corrupt raakt, blijven de andere draaien. Slechts 1 klant heeft dan dus ellende. Maar ... als er iets moet worden gewijzigd in de database, dan moeten alle databases worden aangepast.

Kortom, het is dus een afweging van 'risico beperken' versus onderhoud. Als je genoeg geld en tijd hebt, kun je werken met losse databases en wijzigingen automatiseren.
 
Aad B

Aad B

22/11/2022 10:51:57
Quote Anchor link
Ik denk niet dat het compleet uitgeprogrammameerd is met bedrijfs_id's en dergelijke en dan alle bedrijven in 1 database. Je komt dit wel standaard tegen in SAP en Oracle Applications waar zeer grote organisaties zelf meerdere bedrijven runnen. In kleinere omgevingen zijn de risico's zijn veel te groot. 1 foutje en je kijkt in de boekhouding van een ander bedrijf. Het is veel simpeler om met Virtuals te werken. Vergelijkbaar met Ward ook zegt. VM's kan je schalen op de grootte van een bedrijf en bijbehorende data. Gaat een bedrijf weg of houdt op te bestaan dan stel je de data veilig en gooit de virtual weg. Software changes kan je geautomatiseerd doorvoeren per VM. Een change kan doorgevoerd worden wanneer het (klant)bedrijf daar tijd voor heeft en kan inplannen en dus niet samen met nog 100 andere (de bedrijven van de bedrijfs_id's) moet nadenken en overleggen over een change datum. Het ene bedrijf wil graag in het weekend changes uitvoeren terwijl het andere bedrijf dat doordeweeks moet doen. Kortom dus uitprogarmmeren oftwel softwarematige scheiding 1 database, ik denk het niet.
Gewijzigd op 22/11/2022 10:55:15 door Aad B
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.