Design Tavolo e gerarchie di classi
-
30-09-2019 - |
Domanda
Speriamo che qualcuno può far luce su questo tema attraverso sia un esempio, o forse qualche lettura suggerito. Mi chiedo qual è il miglior approccio di progettazione per le tabelle di modella dopo la loro classe gerarchia equivalenze . Questo può essere meglio descritta con un esempio:
abstract class Card{
private $_name = '';
private $_text = '';
}
class MtgCard extends Card{
private $_manaCost = '';
private $_power = 0;
private $_toughness = 0;
private $_loyalty = 0;
}
class PokemonCard extends Card{
private $_energyType = '';
private $_hp = 0;
private $_retreatCost = 0;
}
Ora, quando si modellano le tabelle per la sincronizzazione con questa gerarchia di classe, sono andato con qualcosa di molto simile:
TABLE Card
id INT, AUTO_INCREMENT, PK
name VARCHAR(255)
text TEXT
TABLE MtgCard
id INT, AUTO_INCREMENT, PK
card_id INT, FK(card.id)
manacost VARCHAR(32)
power INT
toughness INT
loyalty INT
TABLE PokemonCard
id INT, AUTO_INCREMENT, PK
card_id INT, FK(card.id)
hp INT
energytype ENUM(...)
retreatcost INT
Il problema che sto avendo sta cercando di capire come associare ogni record Card
con il record che lo contiene di dati dalla tabella corrispondente. In particolare, come determinare ciò tavolo dovrei essere alla ricerca in.
Dovrei aggiungere una colonna VARCHAR
per Card
per contenere il nome della tabella associata? Questa è l'unica soluzione che i miei colleghi e io sono venuto a, ma sembra troppo "sporco". Mantenere l'estendibile design è la chiave qui, consentendo la facile aggiunta di nuove sottoclassi .
Se qualcuno potesse fornire un esempio o le risorse che mostrano un modo pulito di mirroring gerarchie di classe / da tavolo, sarebbe più apprezzato.
Soluzione
Google "generalizzazione specializzazione modeling relazionale". Troverete diversi ottimi articoli sul tema di come modellare il pattern Gen-spec utilizzando tabelle relazionali. Questa stessa domanda è stato chiesto molte volte in SO, con un po 'diversi dettagli.
Il meglio di questi articoli confermerà la decisione di avere una tabella per i dati generalizzati e tabelle separate per i dati specializzate. La differenza più grande sarà il modo in cui consigliamo di utilizzare chiavi primarie ed esterne. In sostanza, si raccomanda che le tabelle specializzate hanno una sola colonna che fa il doppio dovere. Serve come chiave primaria alla tabella specializzato, ma è anche una chiave esterna che duplica il PK della tabella generalizzata.
Questo è un po 'complicato da mantenere, ma è molto dolce a unirsi a tempo.
Anche tenere a mente che DDL è necessaria quando una nuova classe si aggiunge alla gerarchia.
Altri suggerimenti
In sostanza non.
Dimenticatevi di gerarchie di classi, modelli di stoccaggio, e tutto ciò che è specifico per la vostra applicazione e il vostro particolare linguaggio di app. A meno che non si desidera utilizzare la RDB come una posizione di archiviazione semplice per i tuoi file, uno schiavo dipendente.
Se si desidera che la potenza e la flessibilità (in particolare l'estensibilità) del database relazionale, allora avete bisogno di modellare indipendente da qualsiasi applicazione, e utilizzando i principi RDB, non requisiti linguistici app. Lascia la tua applicazione contesto dietro per un po 'e progettare il database come un database. Ulteriori informazioni su di loro. Normalizzare (eliminare tutte le duplicazioni). Ulteriori informazioni sulle strutture e le regole, e la loro attuazione. Quando lo fate, le vostre domande e la tua "mappatura", sarà senza sforzo. Non ci sarà nessun "impedenza". Utilizzare i tipi di dati corretti e non ci sarà alcun disallineamento.
La struttura si richiede è un normale sottotipo-supertipo. Questi sono i termini di database relazionale che sono state in vigore da oltre 30 anni nel RM, e oltre 23 anni nel settore dei prodotti di database relazionali. Non c'è bisogno di chiamarli divertenti nuovi nomi. Wiki non è un accademico di riferimento, tranne forse per tumori cancerosi.
Dato le tabelle, che sono del tutto corretto come punto di partenza (hai NORMALIZZATO automaticamente), è necessario:
-
Rinomina Card.Id come Card.CardId
-
Rimuovere gli ID per i sottotipi, sono 100% ridondanti; la CardId è sia il PK e FK.
-
Aggiungi un discriminatore Card.CardType CHAR (1) o TINYINT. Ciò consentirà di individuare quale sottotipo di unirsi a, quando il CardType non è noto.
-
Sembra non si capisce appieno il concetto di chiavi esterne, in modo che sarebbe bene ad attrezzarsi per primo. E 'implementato qui nella sua semplice, forma ordinaria:
ALTER TABLE MtgCard
ADD CONSTRAINT Card_MtgCard_fk
FOREIGN KEY (CardId)
REFERENCES Card(CardId)
-
Il rapporto tra Card e MtgCard o PokemonCard è sempre 1 :: 1. Il supertipo è completa solo quando v'è una Card Plus {MtgCard | PokemonCard} con lo stesso CardId. Nel tuo caso non ci può essere un solo sottotipo, facile da applicare con un semplice vincolo CHECK.
-
In altri casi , più di un sottotipo è del tutto legale.
-
I sottotipi ci sono persona è un insegnante o persona è uno studente
-
-
Nel database relazionali non esiste il concetto di unire "da" o "a" (o su / giù o sinistra / destra), quelle nozioni sono lì solo per aiutare noi umani; si può iniziare con qualsiasi / chiave della tabella che hai, e andare a qualsiasi tavolo è necessario. Le tabelle in-tra sono richieste solo in assenza di relazionale identificatori (es. Dove ulteriore replicanti, colonne ID, vengono utilizzati come PK invece di chiavi naturali significativi).
- Nell'esempio, utilizzando i termini, è possibile Vai dritto da iscrizione a persona (ad esempio, per afferrare il Cognome) o < em> a da golf (per afferrare il nome), senza dover visitare i tavoli intermedi; le linee di relazione sono solidi.
.
- Nell'esempio, utilizzando i termini, è possibile Vai dritto da iscrizione a persona (ad esempio, per afferrare il Cognome) o < em> a da golf (per afferrare il nome), senza dover visitare i tavoli intermedi; le linee di relazione sono solidi.
- Ora, le gerarchie di classi ( "è" o "è un") e quant'altro, sono semplici e senza sforzo. Se non appare semplice a voi, si prega di inviare una classe predicato single-economico (in inglese) e Vi fornirò il codice SQL.
di riferimento rapido per standard di database relazionali diagrammi.