Molti a Molti

martedì 20 ottobre 2009 - 18.47

Blacky Profilo | Newbie

Ciao e scusate se oggi ho rotto più del solito, ma sono in via di apprendimento forzato :-)
Ho nel DB una tabella chiamata : Utenti formata da ID_utenti, Nome, Cognome e una chiamata Cellulari formata da ID_Cell, Numero, Marca.
Dato che i numeri non sono fissi e possono variare da dipendente a dipendente, es: oggi nella cesta dei telefoni c'è il nokia con il numero xxxxx domani può non esserci domani l'altro ce ne possono esser 2, ho creato una tabella di correlazione chiamata connex, dove ho inserito id_utenti con id_cell. Nella fase di creazione tabelle li ho relazionati.

Adesso per verificare i telefoni che sono stati assegnati uso questa query:
Essendo una schiappa in SQL l'ho costruita con l'object che permette la progettazione grafica delle query il codice è il seguente

SELECT cellulari.numero, utenti.nome
FROM cellulari
INNER JOIN connex ON cellulari.Id_cell = connex.Id_cell
INNER JOIN utenti ON connex.Id_utente = utenti.Id_utente

Poi ho provato cosi ( a intuito ed il risultato è stato lo stesso)

SELECT cellulari.numero, utenti.nome
FROM cellulari, utenti, connex
WHERE cellulari.Id_cell = connex.Id_cell
AND utenti.Id_utente = connex.Id_utente

Domande:
1)Secondo voi, quali delle 2 sintassi è migliore?
2)Mi potete "tradurre" la sintassi della prima query? tipo DAMMI NOME E NUMERO DA CELLULARI COLLEGAMI etcetc
3)Mi potreste spiegare come creare un constrait in fase di inserimento dati che impedisce l'assegnamento dentro la tabella CONNEX di un nome ad un telefono se l'id del telefono è già nella tabella? (quindi già assegnato)
4)Come posso dire che un utente può avere 300 numeri ma un numero non può avere 300 utlizzatori contemporanei? (quindi nella tabella connex).

Scusate se la domanda è vasta, se vorrete perdere tempo nello spiegare in modo semplice ve ne sarei stra-grata!
Fra



lbenaglia Profilo | Guru

>Ciao e scusate se oggi ho rotto più del solito, ma sono in via
>di apprendimento forzato :-)
>Ho nel DB una tabella chiamata : Utenti formata da ID_utenti,
>Nome, Cognome e una chiamata Cellulari formata da ID_Cell, Numero,
>Marca.
>Dato che i numeri non sono fissi e possono variare da dipendente
>a dipendente, es: oggi nella cesta dei telefoni c'è il nokia
>con il numero xxxxx domani può non esserci domani l'altro ce
>ne possono esser 2, ho creato una tabella di correlazione chiamata
>connex, dove ho inserito id_utenti con id_cell. Nella fase di
>creazione tabelle li ho relazionati.

Ciao Francesca,

Perfetto, hai definito correttamente una relationship molti-a-molti tra le tabelle Utenti e Cellulari.

>Adesso per verificare i telefoni che sono stati assegnati uso
>questa query:
>Essendo una schiappa in SQL l'ho costruita con l'object che permette
>la progettazione grafica delle query il codice è il seguente
>
>SELECT cellulari.numero, utenti.nome
>FROM cellulari
>INNER JOIN connex ON cellulari.Id_cell = connex.Id_cell
>INNER JOIN utenti ON connex.Id_utente = utenti.Id_utente
>
>Poi ho provato cosi ( a intuito ed il risultato è stato lo stesso)
>
>SELECT cellulari.numero, utenti.nome
>FROM cellulari, utenti, connex
>WHERE cellulari.Id_cell = connex.Id_cell
>AND utenti.Id_utente = connex.Id_utente
>
>Domande:
>1)Secondo voi, quali delle 2 sintassi è migliore?
Sono identiche
Durante la fase di ottimizzazione il Query Optimizer genererà il medesimo piano di esecuzione per entrambe.
C'è da dire che con l'avvento dell'operatore JOIN inserito un paio di decenni fa nello standard ANSI SQL, si preferisce utilizzare la prima sintassi in quanto isola la correlazione tra le tabelle da un eventuale filtraggio delle righe risultanti mendiante la clausola WHERE.

>2)Mi potete "tradurre" la sintassi della prima query? tipo DAMMI
>NOME E NUMERO DA CELLULARI COLLEGAMI etcetc
Quella "doppia JOIN" devi intenderla come 2 relationship 1-a-molti e molti-a-1.
Come puoi notare viene eseguita una prima JOIN tra le tabelle cellulari e connex (tra le quali esiste una relationship 1-a-molti) ed il result set proveniente da questa proiezione viene a sua volta messo in JOIN con la tabella utenti (relationship molti-a-1).

>3)Mi potreste spiegare come creare un constrait in fase di inserimento
>dati che impedisce l'assegnamento dentro la tabella CONNEX di
>un nome ad un telefono se l'id del telefono è già nella tabella?
>(quindi già assegnato)
Definisci un constraint UNIQUE sulla colonna Id_cell.

>4)Come posso dire che un utente può avere 300 numeri ma un numero
>non può avere 300 utlizzatori contemporanei? (quindi nella tabella
>connex).
Per come hai definito la struttura del db, 1 numero è associato ad 1 telefono, quindi definendo un constraint UNIQUE sulla colonna Id_cell della tabella connex ottieni che un telefono può essere utilizzato al più da 1 utente, ma 1 utente può avere n telefoni diversi.

>Scusate se la domanda è vasta, se vorrete perdere tempo nello
>spiegare in modo semplice ve ne sarei stra-grata!
E' vasta ma ben posta, quindi è un vero piacere risponderti

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

Blacky Profilo | Newbie

Lory Grazie!!!
Adesso ho capito.

Ti pongo un'ultima domanda, sperando di non abusare troppo del tuo tempo.
Precedentemente mi hai scritto: - Definisci un constraint UNIQUE sulla colonna Id_cell.

L'unico modo che conosco per definire un constraint UNIQUE è quello di piazzare una PK sulla colonna in oggetto (ID_Cell).
Mi son sempre domandata però, se questo metodo, è un metodo barbaro o meno e se, in caso, ce ne fossero di più puliti o indicati.

Spiego meglio: immagino che nella stessa tabella ci possano essere diverse colonne che richiedono univocità, tralasciando il mio esempio, potrei pensare ad una tabella dove l'utente deve inserire i dati di un telefono completo es: numero(univoco), IMEI(univoco), codice_seriale(univoco). Tali dati non potranno mai essere ripetuti all'interno della tabella stessa...

La cosa che mi fà pensare che ciò che faccio non sia proprio sbagliato (ossia di piazzare una PK per definire un constraint unique sui campi che non devono essere ripetuti) è la definizione di PK stessa, ossia una chiave -univoca- che identifica uno ed un solo record di una tabella... Un imei, un numero di sim o quant'altro, a mio avviso, sono bene o male dei candidati ad essere PK.. però sicuramente sbaglio..

P.s. un'altra mia carenza che sto cercando di colmare è la sintassi T-SQL praticamente per piazzare il constraint di cui sopra, apro la tabella nel Microsoft SQL Server Management Studio Express e nella colonna che scelgo (ID_cell in questo caso) ci piazzo una PK (chiave gialla). Esiste un modo di farlo da query?

Merci Beaucoup

Blacky

lbenaglia Profilo | Guru

>L'unico modo che conosco per definire un constraint UNIQUE è
>quello di piazzare una PK sulla colonna in oggetto (ID_Cell).

Un constraint di Primary Key definisce quali colonne identificano univocamente ogni riga nella tabella (il che implicitamente comporta l'univocità dei valori).
In una tabella puoi avere al più una PK.
Un constraint Unique definisce quali colonne devono essere univoche tra tutte le righe della tabella.
In una tabella puoi avere tutti i constraint Unique che ti servono.

Per definirlo utilizza il comando:

ALTER TABLE <schema>.<tabella> ADD CONSTRAINT <nome constraint> UNIQUE(col1,...,col n);

Qui trovi la sintassi completa:
http://msdn.microsoft.com/en-us/library/ms188066.aspx

>Spiego meglio: immagino che nella stessa tabella ci possano essere
>diverse colonne che richiedono univocità, tralasciando il mio
>esempio, potrei pensare ad una tabella dove l'utente deve inserire
>i dati di un telefono completo es: numero(univoco), IMEI(univoco),
>codice_seriale(univoco). Tali dati non potranno mai essere ripetuti
>all'interno della tabella stessa...
Esatto, ed in questi casi è sufficiente definire uno o più constraint Unique.

>La cosa che mi fà pensare che ciò che faccio non sia proprio
>sbagliato (ossia di piazzare una PK per definire un constraint
>unique sui campi che non devono essere ripetuti) è la definizione
>di PK stessa, ossia una chiave -univoca- che identifica uno ed
>un solo record di una tabella... Un imei, un numero di sim o
>quant'altro, a mio avviso, sono bene o male dei candidati ad
>essere PK.. però sicuramente sbaglio..
Attenzione, lo scopo dei due constraint è differente. Le PK ti permettono di identificare univocamente una riga e quindi ti serviranno per definire relationship con altre tabelle; i constraint Unique si limitano a garantire l'univocità di una o più colonne.
Dal punto di vista fisico questa univocità viene realizzata allo stesso modo per entrambi i constraints, ovvero definendo un indice unique sulle colonne interessate.

>P.s. un'altra mia carenza che sto cercando di colmare è la sintassi
>T-SQL praticamente per piazzare il constraint di cui sopra, apro
>la tabella nel Microsoft SQL Server Management Studio Express
>e nella colonna che scelgo (ID_cell in questo caso) ci piazzo
>una PK (chiave gialla). Esiste un modo di farlo da query?
Certo, e te l'ho spiegato sopra

>Merci Beaucoup
Prego

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

Blacky Profilo | Newbie

Fantastico, ho fatto come mi hai suggerito e mi son studiata nel dettaglio il comando.
Non sai quanti dubbi mi hai tolto dalla testa :-)

Sei stato molto carino e gentile.
Ciao!!!

p.s. non credere di esserti liberato di me! tornerò!!!! :-) :-)
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5