Come dovrebbe essere strutturata questa relazione in un database relazionale?

2

In un recente progetto mi è stato chiesto di implementare un sistema di eventi. Un Event doveva avere un Location che originariamente era stato escluso come semplice posizione fisica con alcune note extra opzionali. Poi le specifiche sono cambiate (come hanno l'abitudine di fare) e dovevamo anche avere eventi "online". Questi non avrebbero un indirizzo fisico ma avrebbero comunque bisogno di note su come partecipare (ad esempio l'URL, istruzioni per partecipare).

Abbiamo deciso di adattare la tabella delle posizioni esistente aggiungendo un campo IsOnline e il risultato è stato il seguente:

+-----------------+     +---------------+
|      Event      |     |    Location   |
+-----------------+     +---------------+
| Id              |  .--+ Id            |
| Name            |  |  | Name          |
| Summary         |  |  | Address       |
| Date            |  |  | Postcode      |
| Capacity        |  |  | IsOnline      |
| LocationId      +--'  | Notes         |
+-----------------+     +---------------+

Un esempio di una voce fisica e una voce online nella tabella Località sono simili a questa:

+----+----------------+--------------------------------------+----------+----------+---------------------------------------+
| Id |      Name      |               Address                | Postcode | IsOnline |                 Notes                 |
+----+----------------+--------------------------------------+----------+----------+---------------------------------------+
|  1 | Physical Event | 10 Downing Street, London            | SW1A 2AA |        0 | Ask the policeman to let you in       |
|  2 | Online Event   | http://programmers.stackexchange.com | null     |        1 | You will need a stackexchange account |
+----+----------------+--------------------------------------+----------+----------+---------------------------------------+

Funziona (attualmente) per il nostro caso di uso semplice ma è chiaramente un po 'un trucco e mi ha fatto pensare - quale sarebbe il modo corretto e normalizzato per modellare questo tipo di relazione (Dove un'entità deve avere un A o un B ma non entrambi)?

    
posta AlexFoxGill 22.11.2013 - 12:51
fonte

2 risposte

2

È possibile mantenere i campi comuni a tutte le posizioni in quella tabella, ma disporre di più tabelle che gestiscono tipi di località diversi. Potresti aggiungere una terza tabella di localizzazione come GeoSpacialAddress che avrebbe Lat / Long invece di indirizzi fisici.

Questo impedisce di avere molti campi null. Devi solo essere consapevole delle tue query e potrebbe essere necessario utilizzare UNION per ottenere un elenco completo di tutti gli indirizzi di tipi. "IsOnline" può essere determinato da una posizione con uno o più record di Indirizzo online.

posizione

  • ID
  • Nome
  • Note

OnlineAddress

  • ID
  • LocationID
  • URL

PhysicalAddress

  • ID
  • LocationID
  • Indirizzo
  • Cap

GeoSpacialAddress

  • ID
  • LocationID
  • lat
  • Long
risposta data 22.11.2013 - 14:14
fonte
0

Non dovresti sovraccaricare il tuo modello relazionale con distinzioni che non può fare.

Con tutti i mezzi sfrutta tutta la potenza che ti offre per garantire un buon design e buoni dati; chiavi esterne, vincoli NULL, ecc. sono componenti validi e utili per costruire sistemi affidabili. Tuttavia, un vincolo NULL è un elemento di linguaggio relativamente rozzo; può essere acceso o spento, e questo è praticamente tutto. È quasi certo che prima o poi il tuo modello dovrà riflettere condizioni più complicate, e questo è il punto che hai appena raggiunto. Ne consegue che deve imporre alcune condizioni a un livello di implementazione più elevato, e non importa che il modello di dati non possa seguirne l'esempio.

(Ciò non significa che dovresti abbandonare le possibilità che SQL ti offre, anche quando finiscono per essere ricontrollati dalla logica del business. Difesa in profondità aggiunge un valore molto reale a molti progetti - usa tutto ciò che è utile per difenditi!)

    
risposta data 22.11.2013 - 12:58
fonte

Leggi altre domande sui tag