Mappatura relazionale di oggetti: qual è il modo migliore per implementare i getter?

StackOverflow https://stackoverflow.com/questions/169818

  •  05-07-2019
  •  | 
  •  

Domanda

Cosa dovrebbe succedere quando chiamo $ user- > get_email_address () ?

Opzione 1: estrarre l'indirizzo e-mail dal database su richiesta

public function get_email_address() {
    if (!$this->email_address) {
        $this->read_from_database('email_address');
    }
    return $this->email_address;
}

Opzione 2: estrarre l'indirizzo e-mail (e gli altri attributi utente) dal database durante la creazione dell'oggetto

public function __construct(..., $id = 0) {
    if ($id) {
        $this->load_all_data_from_db($id);
    }
}

public function get_email_address() {
    return $this->email_address;
}

La mia domanda di base è se è meglio ridurre al minimo il numero di query del database o se è meglio ridurre al minimo la quantità di dati che vengono trasferiti dal database.

Un'altra possibilità è che sia meglio caricare gli attributi di cui avrai più bisogno / contenere il minor numero di dati alla creazione dell'oggetto e tutto il resto su richiesta.

Una domanda di follow-up: cosa fanno i framework di astrazione ORM come Activerecord?

È stato utile?

Soluzione

Non c'è davvero una risposta corretta per questo. Dipende dal numero di utenti che stai caricando contemporaneamente, dal numero di campi di testo / BLOB presenti nella tabella Utente, se la tua tabella utente carica oggetti figlio associati. Come dice aaronjensen, questo schema si chiama caricamento lento - e il comportamento opposto (caricamento tutto in avanti nel caso in cui ne abbiate bisogno) è noto come caricamento desideroso .

Detto questo, c'è una terza opzione che potresti prendere in considerazione, che sta caricando lentamente l'intero oggetto Utente quando si accede a una delle sue proprietà:

public function get_email_address() {
    if (!$this->email_address) {
        $this->load_all_data_from_db($this->id)
    }
    return $this->email_address;
}

I vantaggi di questo approccio sono la possibilità di creare una raccolta di utenti (ad esempio un elenco di tutti gli utenti le cui password sono vuote, forse?) basato solo sui loro ID, senza il colpo di memoria di caricare completamente ogni singolo utente, ma poi devi solo una singola chiamata al database per ogni utente per popolare il resto dei campi utente.

Altri suggerimenti

Riduci al minimo il numero di query. Il numero ottimale di query è 0, ma se è necessario eseguire una query perché non è memorizzato nella cache, è 1. La query per ogni proprietà è un modo sicuro per un sistema che non si ridimensionerà mai, ha enormi problemi di contesa e causerà molti più mal di testa di vale la pena.

Dovrei menzionare che c'è un valore nel caricamento lento (che è ciò di cui stai parlando nel passaggio 1) se è improbabile che tu abbia bisogno che i dati vengano caricati pigramente. Se puoi, è meglio essere espliciti e recuperare esattamente o quasi esattamente ciò di cui hai bisogno. Meno tempo spendi per le query, meno tempo la tua connessione è aperta e più il tuo sistema è scalabile.

Sono d'accordo con aaronjensen, tranne quando la quantità di dati che stai estraendo è così grande che inizierai a utilizzare una quantità eccessiva di memoria. Sto pensando dove una riga ha 3 campi di testo che sono tutti abbastanza grandi e tutto ciò che vuoi è il campo ID.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top