Domanda

Un'applicazione web sto lavorando ha rilevato un 'bug' inaspettato -. La banca dati delle app ha due tavoli (tra gli altri) chiamato 'Stati' e 'città'

' States ' campi della tabella:

-------------------------------------------
idStates   |   State   |   Lat   |   Long
-------------------------------------------

' idStates ' è una chiave primaria incremento automatico.

' Città ' campi della tabella:

----------------------------------------------------------
idAreaCode   |   idStates   |   City   |   Lat   |   Long
----------------------------------------------------------

' idAreaCode ' è una chiave primaria che consiste di prefisso codice del paese + (ad esempio 91.422, dove 91 è il codice del paese per l'India e 422 è il codice di una città in India zona). ' idStates ' è una chiave esterna derivato da ' States ' tabella per associare ogni città del ' Città ' tavolo con il suo stato corrispondente.

Abbiamo pensato che il codice del paese + combinazione prefisso sarebbe unico per ogni città, e quindi potrebbero essere tranquillamente utilizzato come chiave primaria. Tutto stava funzionando. Ma una posizione in India ha trovato un 'difetto' inaspettato nella progettazione db - l'India, come gli Stati Uniti sono una democrazia federale e geograficamente divisa in tanti stati o territori dell'Unione. Sia i dati di stati e territori dell'Unione è memorizzato nella ' States ' tavolo. V'è, tuttavia, un unico luogo - Chandigarh - che appartiene a due stati ( Haryana e Punjab ) ed è anche un territorio unione di per sé.

Ovviamente, il design db attuale non ci consente di memorizzare più di un record della citta ' Chandigarh '.

Una delle soluzioni proposte è quello di creare una chiave primaria che unisce le colonne ' idAreaCode ' e ' idStates '.

Mi piacerebbe sapere se questo è possibile la soluzione migliore?

. (FYI: stiamo usando MySQL con il motore InnoDB)


Più informazioni:

  • Le informazioni meteorologiche archivi di database per ogni città. Così, lo stato e la città sono il punto di partenza di ogni query.
  • Dati freschi per ogni città è inserita tutti i giorni utilizzando un file CSV. Il file CSV comprende un idStates (per lo stato) e idAreaCode (per città) colonna che viene utilizzato per identificare ogni record.
  • la normalizzazione del database è importante per noi.

Nota: La ragione per non utilizzare un auto incremento chiave primaria della tabella città è che il database viene aggiornato ogni giorno / ogni ora utilizzando un file CSV (che è generato da un'altra applicazione). E ogni record nel file CSV viene identificato dalla colonna idStates e idAreaCode. Quindi è preferibile che la chiave primaria utilizzata nella tabella città è la stessa per ogni città, anche se la tabella viene eliminato e aggiornato di nuovo. codici postali (o codici PIN) e prefissi (o codici STD) soddisfano i criteri di essere unico, statico (non cambiano spesso) e una lista pronta di questi sono facilmente disponibili. (Abbiamo deciso di prefissi per ora, perché l'India è in procinto di aggiornare i suoi codici pin in un nuovo formato).

  

Il soluzione Abbiamo deciso è stato quello di gestire questo a livello di applicazione, invece di apportare modifiche al disegno di database. Nel database ci sarà memorizzando solo un record di 'Chandigarh'. Nella domanda abbiamo creato una bandiera per qualsiasi ricerca per 'Chandigarh, Punjab' o 'Chandigarh, Haryana' per reindirizzare ricerca a questo record. Sì, non è l'ideale, ma un compromesso accettabile dal momento che questa è l'unica eccezione che abbiamo incontrato finora.

È stato utile?

Soluzione

Sembra che si stanno raccogliendo i dati per un elenco telefonico. Tu sei? Perché sono stati importanti per te? La risposta a questa domanda sarà probabilmente determinare quale progettazione di database che funziona meglio per voi.

Si può pensare che è ovvio ciò che una città è. Non è. Dipende da che cosa avete intenzione di fare con i dati. Negli Stati Uniti, c'è questa unità chiamata MSA (Metropolitan Statistical Area). Il Kansas City MSA si estende sia Kansas City, Kansas e Kansas City, Missouri. Se l'unità MSA senso o non dipende dalla destinazione dei dati. Se è stato utilizzato prefissi negli Stati Uniti per determinare le città, che ci si finisce con un raggruppamento molto diverso da MSA. Anche in questo caso, dipende da che cosa avete intenzione di fare con i dati.

In generale ogni volta che i modelli gerarchici di suddivisioni politiche abbattere, la soluzione più generale è quello di prendere in considerazione la relazione molti-a-molti. A risolvere questo problema nello stesso modo a risolvere altri molti-a-molti problemi. Con la creazione di una nuova tabella, con due chiavi esterne. In questo caso le chiavi esterne sono IdAreacode e IdStates.

Ora si può avere uno arecode in molti stati e uno Stato che abbraccia numerosi prefissi. Sembra un peccato accpet questo overhead extra per coprire una sola eccezione. Sapete se l'eccezione che avete scoperto è solo la punta di un iceberg, e ci sono molti di tali eccezioni?

Altri suggerimenti

Avere una chiave composta potrebbe essere problematico quando si desidera fare riferimento quel tavolo, dal momento che la tabella di riferimento dovrebbe avere tutte le colonne della chiave primaria ha.

Se questo è il caso, si potrebbe desiderare di avere una chiave sequenza primaria, e hanno l'idAreaCode e idStates definiti in un unico gruppo NOT NULL.

Credo che sia meglio aggiungere un altro tavolo, i paesi. Il tuo problema è un esempio per questo database di normalizzazione è importante. Non si può semplicemente combinare chiavi diverse per una colonna.

Quindi, vi suggerisco di creare questi tabella:

Paesi:

+------------+--------------+
| country_id | country_name |
+------------+--------------+

afferma:

+------------+----------+------------+
| country_id | state_id | state_name |
+------------+----------+------------+

città

+------------+----------+---------+-----------+
| country_id | state_id | city_id | city_name |
+------------+----------+---------+-----------+

dati

+------------+----------+---------+---------+----------+
| country_id | state_id | city_id | data_id | your_CSV |
+------------+----------+---------+---------+----------+

I campi in grassetto sono le chiavi primarie. Immettere un country_id standard come 1 per gli Stati Uniti, 91 per l'India, e così via. city_id dovrebbe anche usare il loro id standard.

È quindi possibile trovare qualsiasi cosa appartiene a vicenda piuttosto veloce con il minimo sovraccarico. Tutti i dati possono poi inseriti direttamente alla tabella dati, servendo così come un punto di entrata, la memorizzazione di tutti i dati in un'unica posizione. Non so con mysql, ma se il database di supporto di partizionamento, è possibile partizionare le tabelle di dati in base alle country_id o country_id + state_id a un paio di array di server, così sarà anche accelerare le prestazioni del database in modo considerevole. Il primo, secondo, e terzo tavolo non ci vorrà molto colpito sul carico del server a tutti, e servono solo come riferimento. Si principalmente lavorando sulla tabella di dati quarta. È possibile aggiungere dati tanto quanto si vuole, senza alcun duplicato mai più.

Se si dispone di un solo dati per città, è possibile omettere tabella di dati e passare CSV_data alle città tabella come questa:

città

+------------+----------+---------+-----------+----------+
| country_id | state_id | city_id | city_name | CSV_data |
+------------+----------+---------+-----------+----------+

Se si va con l'aggiunta di una colonna aggiuntiva alla chiave in modo che è possibile aggiungere un ulteriore record per una data città, allora non stai normalizzare correttamente i dati. Dato che hai ora scoperto che una città può essere un membro di più stati, vorrei suggerire di rimuovere ogni riferimento a uno stato dalla tabella Cities, quindi l'aggiunta di una tabella StateCity che permette di relazionarsi con gli Stati a città (la creazione del mattino: m relazione).

Imtroduce una chiave surrogata. Che cosa hai intenzione di fare quando prefissi cambiano numbets o ottenere scissione? Usando chiavi di business come chiave primaria è quasi sempre un errore.

Il vostro sopra sintesi è un altro esempio del perché.

  

"Abbiamo pensato che il codice del paese + combinazione prefisso sarebbe unico per ogni città, e quindi potrebbero essere tranquillamente utilizzato come chiave primaria"

Dopo aver letto questo, ho semplicemente smesso di leggere qualsiasi cosa ulteriormente in questo argomento. Come qualcuno potrebbe capire in questo modo?
prefissi, per definizione (il primo che ho trovato su internet):
  -. "Prefisso è il numero di prefisso che vengono utilizzati per identificare una regione geografica sulla base del Nord America Piano numero Questo numero a 3 cifre può essere assegnato a qualsiasi numero in Nord America, tra cui il Canada, gli Stati Uniti, Messico, America Latina e dei Caraibi"[1]

Mettendo da parte che sono mutevoli e definito solo in Nord America, i prefissi non sono 3-cifre in alcuni altri paesi (3 cifre semplicemente non è sufficiente avere centinaia di migliaia di sedi in alcuni paesi. BTW, zona di mia madre codice ha 5 cifre) e non sono strettamente legata a luoghi geografici fissi.

Prefissi sono la migrazione luoghi come i campi artici alla deriva di ghiaccio, le tribù normadic, la migrazione unità militari o, addirittura, grandi navi oceaniche, ecc

Quindi, per quanto riguarda la fusione di alcune città in uno (o viceversa)?

[1]
http://www.successfuloffice.com/articles/answering-service -Glossario-area-code.htm

Vi consiglio di aggiungere un nuovo campo chiave primaria della tabella Città che sarà semplicemente auto-incrementale. La metodologia BACIO (mantenerlo semplice).

Ogni altra soluzione è ingombrante e confusa, a mio parere.

  1. Il database non è normalizzata. Può essere parzialmente normalizzato. Troverete molti più bug e limitazioni di estensibilità, come risultato.

  2. Una gerarchia di Country quindi State allora il City va bene. Non hai bisogno di una relazione molti-a-molti tabella aggiuntiva come alcuni suggeriscono. La detta città (e molti in America) è moltiplicare in tre Stati.

  3. regole di base di dati di base

    Inserendo CountryCode e AreaCode, concatenati, in un'unica colonna, si è rotto, per non parlare di codice aggiunto ad ogni accesso. Inoltre, CountryCode non è normalizzata.

  4. Il problema è che CountryCode + AreaCode è una buona scelta per una chiave per una città. In termini reali, ha poco a che fare con una città, si applica a enormi distese di terreno. Se il significato di città è stato cambiato in città (come in, la vostra azienda inizia a raccogliere i dati per le grandi città), il db sarebbe rompere completamente.

  5. Mago ha l'unica risposta che è vicino ad essere corretto, che farebbe risparmiare dai tuoi attuali limiti a causa della mancanza di normalizzazione. Non è esatto dire che la risposta di Magician è normalizzata; è corretta scelta di identificatori, che formano una gerarchia in questo caso. Ma vorrei rimuovere le colonne "ID", perché sono inutili, 100% colonne ridondanti, 100% gli indici ridondanti. Le char () colonne sono bene così come sono, e bene per la PK (tasti composti). Ricorda è necessario un indice sulla colonna di char () in ogni caso, per assicurarsi che sia unico nel suo genere.

    • Se tu avessi questo, la struttura relazionale, con identificatori relazionali, il problema non esisterebbe.
    • e gli utenti poveri non devono capire le cose stupide fuori o tenere traccia di identificatori senza senso. Hanno appena stato, naturalmente : State.Name, City.Name, ReadingType, dati ... .
  6. Quando si arriva alla fine inferiore della gerarchia (Città), il PK composto è diventato oneroso (3 x CHAR (20)), e non vorrei portarla nella tabella dei dati (esp se ci sono le importazioni giornaliere CSV e molte letture o righe per città). Quindi per Città unica, vorrei aggiungere una chiave surrogata, come il PK.

  7. Ma per il DDL postato, anche così com'è, senza normalizzare il db e l'utilizzo di identificatori relazionali, sì, il PK della città non è corretta. Dovrebbe essere (idStates, idAreaCode), non il contrario. Che risolverà il problema.

Molto male di denominazione per la via.

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