Pensaci dalla diversa prospettiva e ricorda che non esiste un design di proiettili d'argento.
Che cosa stai cercando di ottenere dal tuo progetto? Vuoi avere i tuoi dati completamente coerenti o ottimizzati per le prestazioni?
I have tables for admin, agent, customer and tables for data storage like city, services, category, sub-category, gender.
Amministratore, Agente e Cliente sembrano entità nel tuo dominio. Attuerai alcune logiche di business intorno a loro, quindi ha senso definire le classi appropriate. Di solito i dati per ciascuna di tali classi sono contenuti all'interno di una singola tabella in DB (non potrebbe essere il caso per le entità derivate).
La città potrebbe essere vista in modo diverso. La città ha alcune proprietà, come i riferimenti ai servizi o categorie (esattamente questa direzione della relazione) o il nome di un paese simile? Se provo a rimuovere la città da DB, dovrei rimuovere tutti i clienti associati alla città o almeno impedire la rimozione della città? Se le risposte a queste domande sono "Sì", la città ha alcune proprietà, quindi è un'entità nel dominio aziendale e dovrebbe essere definita come classe. Se la risposta è "No" e sai che la città nel tuo dominio è solo il nome della città, non devi definire la città come classe.
Dal punto di vista della programmazione, ti piacerebbe lavorare con qualcosa come $customer->getCity()->getName()
(città definita come entità) o $customer->getCity()
(città definita come stringa)? Nel primo caso, avrai sempre JOIN ad un certo punto, sia durante il recupero di $customer
da DB (strategia desiderosa) o durante la chiamata a getCity()
(strategia lazy). Nel secondo caso, la città sarà inline nella stessa tabella del cliente, quindi avrai prestazioni migliori per le operazioni di massa (come il recupero di 10K clienti con il tuo ORM).
Ok, la città è un'entità piuttosto complicata da discutere senza conoscere il tuo dominio problematico, ma ad es. il genere non vale sicuramente la pena di definire come classe. Quanto spesso cambierai genere nel tuo sistema? Hai davvero bisogno di CRUD o hai abbastanza liste di genere? Dalla mia esperienza di sviluppo, abbiamo avuto sesso come enum per 3 anni senza apportare alcuna modifica alla lista dei generi. È abbastanza sicuro che tu possa definirlo come enum.
Il meccanismo concreto per collegare un enumerario come il genere alla proprietà dipende dal tuo quadro di riferimento. Per esempio. in Doctrine puoi usare link per implementare enumerazioni astratte per la proprietà. Ad esempio, i valori concreti delle scelte per enum possono essere recuperati dal database durante il riscaldamento della cache o l'inizializzazione dell'app.
Ricorda, più entità interconnesse hai, più problemi di prestazioni avrai in futuro (a causa dei JOIN eseguiti durante ogni query). Alla fine, la progettazione può evolversi e l'esecuzione delle migrazioni dei dati non è così difficile se si dispone di database adeguatamente progettati in ogni fase della vita dell'applicazione (almeno si hanno chiavi primarie e chiavi esterne che riflettono il proprio dominio). Il modo migliore per iniziare a progettare la tua app / database è:
- Comprendi il dominio del problema (quali entità ci sono, quali flussi di dati hai).
- Costruisci ERD del tuo dominio aziendale (un buon libro introduttivo sull'argomento potrebbe essere "Learning MySQL" di Hugh Williams, Seyed Tahaghoghi).
- Crea la prima versione dello schema del database e evolvila nel tempo in base ai requisiti aziendali imminenti.
- Aggiungi il codice di connessione del database dell'app per adattarlo alla progettazione del tuo database (in genere il database è più lungo del codice).
Un altro buon libro per la lettura è "Refactoring Databases: Evolutionary Database Design" di Scott W. Ambler, Pramodkumar J. Sadalage.
TL; DR Non cercare di adattare il design di conseguenza agli strumenti che hai, invece di creare un design appropriato per il tuo dominio problematico e selezionare gli strumenti che ti aiuteranno a implementarlo.
Spero che questo fornisca alcune informazioni.