Newsgroup: it.comp.software.database
Titolo: Dati non ridondanti

Ciao, ho questo dubbio:
Dovrei fare due (o più) tabelle che abbiano queste caratteristiche:
Una deve contenere l'anagrafica dei dipendenti di una ditta. Chiave della
tabella ID(oppure combinazione Nome+Cognome)
L'altra , è una tabella che conterrà i "ruoli" possibili di tali dipendenti
(direttore, meccanico, operaio..ect) chiave della tabella ID.
Come potrei organizzare i dati supposto che un dipendente può ricoprire PIU'
di un ruolo?
penso potrei farla cosi:
TabAnagrafica
ID chiave
IDRuolo collegamento con il ruolo
Nome
...
ma poi?
se volessi attribuire a una persona più ruoli?
Pensavo:
TabAnagrafica
ID chiave
Ruolo1 si/no
Ruolo2 si/no
Ruolo3 si/no
Ruolo4 si/no
Nome
...
Ma, calcolando che si puo sia avere piu ruoli che anche solo uno cosi mi
sembra un po' ridondante...
Consigli ?
Grazie in anticipo.
fabriZIo
--------------------------------
Inviato via 
http://usenet.libero.it

di un ruolo?
Relazione molti a molti. Conviene per lo più fare così:
- persone
id_persona PK
cognome
nome
....
- ruoli
id_ruolo PK
descrizione_ruolo
- incarichi
id_persona PK,FK
id_ruolo PK,FK
Ciao
Matteo

Grazie in anticipo.
prego
Kylnas

Ruolo4 si/no
Questa struttura e' sicuramente inopportuna non essendo
neanche in prima forma normale.
Fai ben attenzione al fatto che potresti volere anche tenere
traccia del fatto che un impiegato nel tempo ha cambiato ruolo.
In questo caso la tabella proposta da Lorenzo dovrebbe prevedere
due attributi in piu': la data di inizio e fine di validita'
copertura della carica.
Una tabella di questo tipo si dice anche di tipo
"valid-time state table", e prevede tutta una
serie di accorgimenti (ad esempio la definizione
della chiave primaria non e' piu' cosi' banale).
Se vuoi sapere di piu' su come gestire tali
tematiche, ti consiglio questo libro:
"Developing Time-Oriented Database Applications in SQL"
di Richard T. Snodgrass edito da Morgan Kaufmann
(prefazione di Jim Gray)
Non ho ben capito esattamente cosa intendi fare
per la chiave, ma sappi che generalmente utilizzare
come chiave gli attributi nome e cognome non e' una
strategia vincente.
Anche se per il tuo universo di discussione (la realta'
rappresentata dal tuo modello dati concettuale)
potrebbe essere corretto ora, nulla vieta che in futuro
ci siano in azienda due Mario Rossi per esempio.
Tenerne conto ora costo molto poco, modificare il
modello concettuale in futuro potrebbe costare molto.
Attenzione anche al fatto che concatenare il valore
di due attributi (ad esempio un attributo identificativo
fatto dal nome+cognome) viola i principi basilari
di modellazione.
Se non esiste una chiave naturale (ad esempio un codice
gia' utilizzato in azienda), l'introduzione di una
chiave surrogata e' sempre ammissibile, ma non deve
essere legata in alcun modo al valore di altri attributi
(la chiave surrogata ideale e' un campo numerico progressivo
o assolutamente random).
Ciao,
-- 
Gianluca Hotz
Backoffice MVP (SQL Server) MCP SQL Server and MCP Windows
Vice-President of the Italian User Group for SQL Server
Founding Member of the Italian User Group for .NET
http://www.ghotz.com
http://www.ugiss.org
Gianluca. 

della chiave primaria non e' piu' cosi' banale).
Questo è molto interessante.
La chiave primaria a quel punto come potrebbe essere definita?
Conviene fare una chiave surrogata?
Matteo

 Conviene fare una chiave surrogata?
Da quanto ho letto (Date, Pascal) il fatto di adottare una
chiave surrogata puo' essere una strategia vincente, ma in
un caso come questo solo per semplificare le query ed aumentare
la stabilita' della chiave primaria (c'e' anche il benefico
effetto collaterale di un aumento delle prestazioni).
Idealmente la chiave surrogata non deve essere dipendente dal
valore degli altri attributi quindi da un punto di vista
della semplificazione dei vincoli da applicare per garantire
l'univocita' delle righe non porta alcun beneficio.
Ciao,
-- 
Gianluca Hotz
Backoffice MVP (SQL Server) MCP SQL Server and MCP Windows
Vice-President of the Italian User Group for SQL Server
Founding Member of the Italian User Group for .NET
http://www.ghotz.com
http://www.ugiss.org
--
USE tempdb
GO
IF OBJECT_ID('dbo.ruolipersone') IS NOT NULL
 DROP TABLE dbo.ruolipersone
GO
IF OBJECT_ID('dbo.persone') IS NOT NULL
 DROP TABLE dbo.persone
GO
IF OBJECT_ID('dbo.ruoli') IS NOT NULL
 DROP TABLE dbo.ruoli
GO
CREATE TABLE dbo.persone (
 IDPersona int   NOT NULL,
 NomePersona varchar(20) NOT NULL,
 CONSTRAINT pk_persone
 PRIMARY KEY (IDPersona),
 CONSTRAINT ak_persone
 UNIQUE  (NomePersona)
)
GO
INSERT dbo.persone VALUES (1, 'Pippo')
INSERT dbo.persone VALUES (2, 'Pluto')
GO
CREATE TABLE dbo.ruoli (
 IDRuolo  int   NOT NULL,
 NomeRuolo varchar(20) NOT NULL,
 CONSTRAINT pk_ruoli
 PRIMARY KEY (IDRuolo),
 CONSTRAINT ak_ruoli
 UNIQUE  (NomeRuolo)
)
GO
INSERT dbo.ruoli VALUES (1, 'Ruolo 1')
INSERT dbo.ruoli VALUES (2, 'Ruolo 2')
GO
CREATE TABLE dbo.ruolipersone (
 IDPersona int   NOT NULL,
 IDRuolo  int   NOT NULL,
 DataInizio datetime NOT NULL,
 DataFine datetime NOT NULL,
 CONSTRAINT pk_ruolipersone_temp
 UNIQUE  (IDPersona, IDRuolo,
    DataInizio, DataFine),
 CONSTRAINT fk_ruolipersone_to_persone
 FOREIGN KEY (IDPersona)
 REFERENCES dbo.persone (IDPersona),
 CONSTRAINT fk_ruolipersone_to_ruoli
 FOREIGN KEY (IDRuolo)
 REFERENCES dbo.ruoli (IDRuolo)
)
GO
CREATE TRIGGER tg_ruolipersone_temp
ON dbo.ruolipersone
FOR INSERT, UPDATE
AS
IF (EXISTS
      (SELECT *
       FROM   dbo.ruolipersone AS I1
       WHERE  1 < (SELECT COUNT(idpersona)
                   FROM   dbo.ruolipersone AS I2
                   WHERE  I1.idpersona = I2.idpersona
                     AND  I1.idruolo = I2.idruolo
                     AND  I1.datainizio < I2.datafine
                     AND  I2.datainizio < I1.datafine
       )))
BEGIN
 RAISERROR ('Violazione chiave primaria temporale', 16, 1)
 ROLLBACK TRANSACTION
END
GO
-- corretto (e' il primo...)
INSERT dbo.ruolipersone
VALUES (1, 1, '1996-01-01', '1996-06-01')
GO
-- Errore vincolo UNIQUE
INSERT dbo.ruolipersone
VALUES (1, 1, '1996-01-01', '1996-06-01')
GO
-- Errore vincolo trigger
INSERT dbo.ruolipersone
VALUES (1, 1, '1996-04-01', '1996-06-01')
-- corretto (coincidenza inizio con fine precedente)
INSERT dbo.ruolipersone
VALUES (1, 1, '1996-06-01', '1999-06-01')
-- corretto (senza coincidenza inizio con fine precedente)
INSERT dbo.ruolipersone
VALUES (1, 1, '2000-01-01', '2002-01-01')
-- Errore (ancora una volta, sovrapposizione)
INSERT dbo.ruolipersone
VALUES (1, 1, '1999-04-01', '1999-06-01')
-- Corretto (anche se spesso in una tabella di questo
-- tipo non si vuole permettere un inserimento nel
-- passato
INSERT dbo.ruolipersone
VALUES (1, 1, '1999-10-01', '1999-12-31')

 [snip!]
Che dire? Ti ringrazio per la completezza con cui mi rispondi.
Ho stampato il tuo post per leggerlo con attenzione. 
Mi rendo conto però che sviluppare un database che tenga memoria dello
"storico" sia molto più complesso di quanto possa sembrare.
In effetti non avevo mai riflettuto sul fatto che in questo caso ci si
scontra con problemi di integrità e di ridondanza nei dati, problemi
che i metodi "usuali" non sono sufficienti a controllare.
Mi chiedo se ciò deriva da una limitazione intrinseca del modello
relazionale (per quel poco che lo conosco). 
Grazie ancora, un saluto
Matteo

 relazionale (per quel poco che lo conosco).
Se non ricordo male ho letto nei titoli di qualche bibliografia
che alcuni accademici hanno fatto delle pubblicazioni dove
si parla esplicitamente di estensione del modello relazionale
per gestire queste problematiche.
Se non ricordo male pero' Date nel suo libro dissente da questa
posizione, ribadendo (come del resto fa' da decenni) che la
tacnologia relazionale in quanto tale e' completa, dovrebbe essere
solo implementata coerentemente dai produttori di RDBMS e da
chi definisce gli standard (ad esempio SQL).
Snodgrass mi sembra piu' pragmatico, studia a fondo come gestire
la materia con l'ANSI SQL ed ha proposto svariate estensioni allo
standard per rendere piu' pratica sia la definizione dei vincoli
che la definizione delle richieste.
Non ne sono sicurissimo, devo ancora leggere le pubblicazioni
che ha fatto, inoltre Date e' una voce piu' che autorevole e
vorrei anche leggere un altro libro che consiglia lui.
Comunque sia, per non fare troppo i teorici, le problematiche
ci sono ed a quanto pare anche gli studiosi che cercano in un
modo o nell'altro di affrontarla (basta dare uno sguardo a
questa statistica, purtroppo aggiornata solo al 1996, del
trend relativo alle pubblicazioni legate ai "database temporali"
http://liinwww.ira.uka.de/bibliography/Database/time.html
).
Sempre dal sito Timecentral trovi un link ad un front-end
per fare "database temporali", come prodotto lascia un
po' il tempo che trova, ma ci sono degli esempi interessanti
di come estendere il linguaggio DML per gestire le richieste
http://www.timeconsult.com/TemporalData/TemporalDBMS.html


Gianluca Hotz wrote:
<cuttone>...
beh, tanto di cappello, Gianluca :-)
Una sintesi chiarissima e utilissima su un problema "tosto" e che non 
capita certo  tutti i gironi di affrontare.
Locked :-)
Ciao e grazie!
Fabrizio

 chi definisce gli standard (ad esempio SQL).
Solo un piccolo aggiornamento, Date, Darwen e Lorentzos affrontano
il problema nel libro "Temporal Data and the Relational Model".
Maggiori informazioni sul sito 
http://www.thethirdmanifesto.com
dove ci sono anche alcuni interessanti documenti.


Chiedo immensamente perdono per il ritardo con cui ringrazio tutti quelli
che mi hanno risposto.
E un particolare grazie a Gianluca, davvero un pozzo di saggezza e cultura
per "noi" comuni mortali.....
:)))
fabriZio