Quando dovrei usare il rapporto uno a uno?


92

Ci scusiamo per questa domanda da noob, ma c'è davvero bisogno di usare una relazione uno a uno con le tabelle nel tuo database? Puoi implementare tutti i campi necessari all'interno di una tabella. Anche se i dati diventano molto grandi, puoi enumerare i nomi delle colonne di cui hai bisogno SELECTnell'istruzione invece di usare SELECT *. Quando hai davvero bisogno di questa separazione?

Risposte:


105

1 a 0..1

  • Il valore "da 1 a 0..1" tra super e sottoclassi viene utilizzato come parte della strategia "tutte le classi in tabelle separate" per l' implementazione dell'ereditarietà .

  • Un valore da "1 a 0..1" può essere rappresentato in una singola tabella con la parte "0..1" coperta da campi NULL. Tuttavia, se la relazione è principalmente "1 a 0" con solo poche righe "1 a 1", suddividere la parte "0..1" in una tabella separata potrebbe far risparmiare alcuni vantaggi di archiviazione (e prestazioni della cache). Alcuni database sono più parsimoniosi nella memorizzazione di NULL rispetto ad altri, quindi un "punto limite" in cui questa strategia diventa praticabile può variare notevolmente.

1 a 1

  • Il vero "1 a 1" partiziona verticalmente i dati, il che può avere implicazioni per la memorizzazione nella cache. I database in genere implementano le cache a livello di pagina, non a livello di singoli campi, quindi anche se selezioni solo pochi campi da una riga, in genere l'intera pagina a cui appartiene la riga verrà memorizzata nella cache. Se una riga è molto ampia ei campi selezionati relativamente stretti, finirai per memorizzare nella cache molte informazioni di cui non hai effettivamente bisogno. In una situazione del genere, può essere utile partizionare verticalmente i dati, in modo che solo la parte o le righe più strette e usate più frequentemente vengano memorizzate nella cache, quindi più di esse possono essere inserite nella cache, rendendo la cache effettivamente "più grande".

  • Un altro utilizzo del partizionamento verticale è quello di modificare il comportamento di blocco: i database in genere non possono bloccare a livello di singoli campi, ma solo di intere righe. Dividendo la riga, si consente che un blocco avvenga solo su una delle sue metà.

  • Anche i trigger sono in genere specifici della tabella. Sebbene tu possa teoricamente avere solo una tabella e fare in modo che il trigger ignori la "metà sbagliata" della riga, alcuni database potrebbero imporre limiti aggiuntivi su ciò che un trigger può e non può fare che potrebbero renderlo impraticabile. Ad esempio, Oracle non ti consente di modificare la tabella mutante: avendo tabelle separate, solo una di esse potrebbe essere mutante, quindi puoi ancora modificare l'altra dal tuo trigger.

  • Tabelle separate possono consentire una protezione più granulare.

Queste considerazioni sono irrilevanti nella maggior parte dei casi, quindi nella maggior parte dei casi dovresti considerare di unire le tabelle "1 a 1" in un'unica tabella.


20

Se i dati in una tabella sono correlati, ma non "appartengono" all'entità descritta dall'altra, allora è un candidato per mantenerli separati.

Ciò potrebbe fornire vantaggi in futuro, se i dati separati devono essere correlati anche a qualche altra entità.


19

Se metti due tabelle uno a uno in una, è probabile che avrai problemi di semantica. Ad esempio, se ogni dispositivo ha un telecomando, non suona abbastanza bene posizionare il dispositivo e il telecomando con le loro caratteristiche in una tabella. Potrebbe anche essere necessario passare del tempo a capire se un determinato attributo appartiene al dispositivo o al telecomando.

Potrebbero verificarsi casi in cui metà delle colonne rimarrà vuota per un lungo periodo o non verrà mai compilata. Ad esempio, un'auto potrebbe avere un rimorchio con un sacco di caratteristiche o potrebbe non averne nessuno. Quindi avrai molti attributi inutilizzati.

Se la tua tabella ha 20 attributi e solo 4 di essi vengono utilizzati occasionalmente, ha senso suddividere la tabella in 2 tabelle per problemi di prestazioni.

In questi casi non è bene avere tutto in una tabella. Inoltre, non è facile gestire una tabella che ha 45 colonne!


17

I miei 2 centesimi.

Lavoro in un luogo in cui tutti sviluppiamo un'applicazione di grandi dimensioni e tutto è un modulo. Ad esempio, abbiamo una userstabella e un modulo che aggiunge i dettagli di Facebook per un utente, un altro modulo che aggiunge i dettagli di Twitter a un utente. Potremmo decidere di scollegare uno di quei moduli e rimuovere tutte le sue funzionalità dalla nostra applicazione. In questo caso, ogni modulo aggiunge la propria tabella con relazioni 1: 1 alla userstabella globale , in questo modo:

create table users ( id int primary key, ...);
create table users_fbdata ( id int primary key, ..., constraint users foreighn key ...)
create table users_twdata ( id int primary key, ..., constraint users foreighn key ...)

13

Il momento più sensato per usarlo sarebbe se ci fossero due concetti separati che si relazionerebbero solo in questo modo. Ad esempio, un'auto può avere un solo conducente corrente e il conducente può guidare solo un'auto alla volta, quindi la relazione tra i concetti di auto e conducente sarebbe 1 a 1. Accetto che questo sia un esempio artificioso per dimostrare il punto.

Un altro motivo è che vuoi specializzare un concetto in modi diversi. Se si dispone di una tabella Persona e si desidera aggiungere il concetto di diversi tipi di Persona, come Dipendente, Cliente, Azionista, ognuno di questi richiederebbe diversi set di dati. I dati che sono simili tra loro sarebbero sulla tabella Persona, le informazioni specialistiche sarebbero sulle tabelle specifiche per Cliente, Azionista, Dipendente.

Alcuni motori di database hanno difficoltà ad aggiungere in modo efficiente una nuova colonna a una tabella molto grande (molte righe) e ho visto tabelle di estensione utilizzate per contenere la nuova colonna, piuttosto che la nuova colonna aggiunta alla tabella originale. Questo è uno degli usi più sospetti di tabelle aggiuntive.

Puoi anche decidere di dividere i dati per un singolo concetto tra due diverse tabelle per problemi di prestazioni o leggibilità, ma questo è un caso ragionevolmente speciale se stai partendo da zero: questi problemi verranno visualizzati in seguito.


5

Non molto spesso.

potresti trovare qualche vantaggio se hai bisogno di implementare un po 'di sicurezza, quindi alcuni utenti possono vedere alcune delle colonne (tabella1) ma non altre (tabella2) ..

ovviamente alcuni database (Oracle) consentono di eseguire questo tipo di sicurezza nella stessa tabella, ma altri no.


5

Ti riferisci alla normalizzazione del database. Un esempio a cui posso pensare in un'applicazione che gestisco è Items. L'applicazione consente all'utente di vendere molti diversi tipi di articoli (es. InventoryItems, NonInventoryItems, ServiceItems, ecc ...). Sebbene sia possibile memorizzare tutti i campi richiesti da ogni articolo in una tabella Articoli, è molto più facile mantenere una tabella Articoli di base che contenga campi comuni a tutti gli articoli e quindi tabelle separate per ogni tipo di articolo (ad esempio Inventario, Non Inventario, ecc ..) che contengono campi specifici solo per quel tipo di elemento. Quindi, la tabella degli elementi avrebbe una chiave esterna per il tipo di elemento specifico che rappresenta. La relazione tra le tabelle degli articoli specifici e la tabella degli articoli di base sarebbe uno a uno.

Di seguito, un articolo sulla normalizzazione.

http://support.microsoft.com/kb/283878


3

Come per tutte le domande sul design, la risposta è "dipende".

Ci sono alcune considerazioni:

  • quanto sarà grande la tabella (sia in termini di campi che di righe)? Può essere scomodo ospitare il nome utente, la password con altri dati di uso meno comune sia dal punto di vista della manutenzione che della programmazione

  • i campi nella tabella combinata che hanno vincoli potrebbero diventare complicati da gestire nel tempo. ad esempio, se un trigger deve essere attivato per un campo specifico, ciò avverrà per ogni aggiornamento della tabella indipendentemente dal fatto che quel campo sia stato interessato.

  • quanto sei sicuro che il rapporto sarà 1: 1? Come sottolinea questa domanda, le cose possono complicarsi rapidamente.


3

Un altro caso d'uso può essere il seguente: potresti importare dati da qualche fonte e aggiornarli quotidianamente, ad esempio informazioni sui libri. Quindi, aggiungi tu stesso i dati su alcuni libri. Quindi ha senso mettere i dati importati in un'altra tabella rispetto ai tuoi dati.


2

Normalmente incontro due tipi generali di relazione 1: 1 nella pratica:

  1. Relazioni IS-A, note anche come relazioni supertipo / sottotipo. Questo è quando un tipo di entità è in realtà un tipo di un'altra entità (EntityA IS A EntityB). Esempi:

    • Persona giuridica, con entità separate per contabile, ingegnere, venditore, all'interno della stessa azienda.
    • Entità oggetto, con entità separate per Widget, RawMaterial, FinishedGood, ecc.
    • Entità auto, con entità separate per camion, berlina, ecc.

    In tutte queste situazioni, l'entità del supertipo (es. Persona, Oggetto o Auto) avrebbe gli attributi comuni a tutti i sottotipi e le entità del sottotipo avrebbero attributi univoci per ogni sottotipo. La chiave primaria del sottotipo sarebbe la stessa di quella del supertipo.

  2. Relazioni "Boss". Questo è quando una persona è l'unico capo o manager o supervisore di un'unità organizzativa (dipartimento, azienda, ecc.). Quando è consentito un solo capo per un'unità organizzativa, esiste una relazione 1: 1 tra l'entità persona che rappresenta il capo e l'entità unità organizzativa.


1
Mi piace il secondo esempio. Puoi avere l'entità "Reparto" e l'entità "Dipendente". In un reparto hai molti dipendenti e un dipendente può lavorare solo in un reparto. Questo è 1: n. Un dipendente può essere il supervisore di un dipartimento, solo di un dipartimento e il dipartimento ha un solo supervisore. Quindi finisci con due tabelle collegate con due relazioni: 1: ne 1: 1.
cezar

2

In primo luogo, penso che sia una questione di modellare e definire cosa sia un'entità separata. Supponi di avere customerscon uno e un solo singolo address. Ovviamente potresti implementare tutto in un'unica tabella customer, ma se, in futuro, gli permetti di avere 2 o più indirizzi, allora dovrai rifattorizzarlo (non è un problema, ma prendi una decisione consapevole).

Posso anche pensare a un caso interessante non menzionato in altre risposte in cui potrebbe essere utile dividere la tabella:

Immagina, ancora una volta, di avere customersun singolo addressciascuno, ma questa volta è facoltativo avere un indirizzo. Ovviamente potresti implementarlo come un gruppo di NULLcolonne -able come ZIP,state,street. Ma supponiamo che dato che si hanno un indirizzo lo Stato non è un optional, ma la zip è. Come modellarlo in una singola tabella? Potresti usare un vincolo sulla customertabella, ma è molto più facile dividere in un'altra tabella e rendere NULLable la foreign_key. In questo modo il tuo modello è molto più esplicito nel dire che l' entità address è opzionale e che ZIPè un attributo opzionale di quell'entità.


0

Ai tempi della programmazione l'ho riscontrato solo in una situazione. Che è quando c'è una relazione 1-a-molti e 1-a-1 tra le stesse 2 entità ("Entità A" e "Entità B").

Quando "Entità A" ha più "Entità B" e "Entità B" ha solo 1 "Entità A" e "Entità A" ha solo 1 "Entità B" corrente e "Entità B" ha solo 1 "Entità A".

Ad esempio, un'auto può avere un solo conducente corrente e il conducente può guidare solo un'auto alla volta, quindi la relazione tra i concetti di auto e conducente sarebbe 1 a 1. Ho preso in prestito questo esempio dalla risposta di @Steve Fenton

Dove un conducente può guidare più auto, ma non contemporaneamente. Quindi le entità Car e Driver sono 1-a-molti o molti-a-molti. Ma se abbiamo bisogno di sapere chi è il driver corrente, allora abbiamo anche bisogno della relazione 1 a 1.


0

Un altro caso d'uso potrebbe essere il superamento del numero massimo di colonne nella tabella del database. Quindi potresti unirti a un altro tavolo usando OneToOne

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.