Come dividere una tabella in base ai suoi tipi di figlio

0

Abbiamo una tabella con un mucchio di colonne. Diciamo che rappresenta gli umani. Ogni essere umano ha un tipo specifico: arciere-umano, auto-umano e così via. Ogni volta che creiamo una riga, quasi tutti i campi sono vuoti poiché creiamo un essere umano di un solo tipo.

Ad esempio:

| ID | Forenamne | Surname | Arrows | Bow      | Car-Manufacturer | Car-Color | ....
| 0  | John      | Doe     | 5      | Compound | null             | null      |
| 1  | Peter     | Smith   | null   | null     | Toyota           | Blue      |

Come puoi vedere ci sono già due valori nulli e ci sono solo due gruppi con due valori ciascuno (in realtà ciò equivale a circa 20 * 30).

Abbiamo discusso diverse pratiche:

a) Creiamo tabelle con dati anagrafici: arcieri-umani, auto-umani

Questo non funziona poiché si dovrebbe avere una chiave straniera nella tabella "umani" e non si può veramente dire se è necessario collegarsi agli arcieri-umani o agli auto-umani.

b) Creiamo tabelle con dati anagrafici: arcieri umani, auto-umani e aggiungi una chiave esterna per ciascuno.

Esempio:

| ID | Forenamne | Surname | Archer-ID | Car-ID | ....
| 0  | John      | Doe     | 13        | null   | 
| 1  | Peter     | Smith   | null      | 37     |

Questo odora, vero?

c) Posizioniamo la chiave esterna nelle tabelle dei dati master (come suggerito da Vlad )

Esempio:

HUMAN

| ID | Forename | Surname | Type   |
| 0  | John     | Doe     | Archer |
| 1  | Peter    | Smith   | Car    |
| 2  | Peter    | Doe     | null   |

ARCHER

| HUMAN_ID | Arrows | Bow      |
| 0        | 5      | Compound |

CAR

| HUMAN_ID | Manufacturer | Color |
| 1        | Toyota       | Blue  |

Questo non funziona poiché non è possibile determinare la tabella dei dati master corretta. Il problema: quante frecce ha John Doe? non può essere risolto:

SELECT ???.ARROWS FROM HUMAN JOIN ??? ON HUMAN.ID LIKE ??? WHERE HUMAN.FORENAME LIKE 'JOHN' AND HUMAN.SURNAME LIKE 'DOE'

Hai bisogno della logica per determinare la tabella giusta in base alla colonna del tipo e che sicuramente è un odore.

Qualche idea su come dividere questa tabella per evitare 100 campi null per ogni riga?

    
posta OddDev 08.11.2016 - 15:00
fonte

3 risposte

3

Cosa c'è che non va nella normalizzazione dei dati standard?

HUMAN

| ID | Forename | Surname | Type   |
| 0  | John     | Doe     | Archer |
| 1  | Peter    | Smith   | Car    |
| 2  | Peter    | Doe     | null   |

ARCHER

| HUMAN_ID | Arrows | Bow      |
| 0        | 5      | Compound |

CAR

| HUMAN_ID | Manufacturer | Color |
| 1        | Toyota       | Blue  |
    
risposta data 08.11.2016 - 15:43
fonte
2

Quello che stai facendo è uno dei modi più ragionevoli per supportare il polimorfismo all'interno del modello relazionale generico.

Uno svantaggio è la mancanza di identificazione del vero tipo della riga, ma puoi aggiungere una colonna stringa che cattura un nome per il tipo.

Un altro svantaggio è che non possiamo applicare i raggruppamenti delle colonne opzionali - impedire l'utilizzo di colonne inappropriate per un tipo, o mandare tutte le colonne per un determinato tipo sono presenti.

Ancora, che ci crediate o no, questa è una mappatura ragionevole di una gerarchia di classi. Le parti migliori di questo approccio sono che gli ID sono facili da gestire e, le query sono ragionevoli.

Per ulteriori informazioni sulla modellizzazione dell'ereditarietà nei db relazionali, vedi:

Un'illustrazione di tre diversi modi (incluso l'approccio opzionale per le colonne), ognuno dei quali presenta alcuni inconvenienti (che considero peggiori di quelli per ciò che si sta facendo): link

Un altro approccio, il modello nordico di Microsoft , è una grande differenza rispetto al modello relazionale standard; è quasi come fare RDF in SQL.

    
risposta data 08.11.2016 - 16:10
fonte
0

Vorrei memorizzare tali informazioni in una colonna HSTORE se si utilizza PostgreSQL link o JSON se si utilizza MySQL link

    
risposta data 08.11.2016 - 15:18
fonte

Leggi altre domande sui tag