Mysql e chiavi esterne

Nel mio db utilizzo diverse tabelle con diverse chiavi esterne.

Tuttavia, le restrizioni imposte da mysql per le foreign key sono più
alte di quanto io necessiti, in quanto io vorrei avere l’opportunità di
settare il campo della chiave esterna come nullo o ‘0’, senza
preoccuparmi di avere una reale corrispondenza di chiave.

Ho provato a guardare qui
http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html
ma non sono riuscito a impostare valori nulli senza ricevere il dannato
errore:
“ERROR 1216 (23000): Cannot add or update a child row: a foreign key
constraint fails”

Allora mi sto chiedendo, poichè Rails non è in grado di determinare
automaticamente le corrispondenze tra le tabelle - sembra dunque una
formalità definire chiavi esterne - non potrei non segnalare a mysql le
foreign key e nella logica del db definire semplici campi int?

Alla fine il lavoro di “trasformazione della corrispondenza” si fa
attraverso has_many, belgons_to etc…

No?

Sto sbagliando?

Tuttavia, le restrizioni imposte da mysql per le foreign key sono più
alte di quanto io necessiti, in quanto io vorrei avere l’opportunità di
settare il campo della chiave esterna come nullo o ‘0’, senza
preoccuparmi di avere una reale corrispondenza di chiave.

Allora non e` esattamente una chiave esterna, oppure il tuo DB forse
potrebbe essere strutturato in modo diverso. Avere una chiave esterna
che non punta a nulla viola la ‘referential integrity’. Forse
potresti avere, nella tabella ‘target’, una riga a cui puntare per le
righe nella tabella di partenza ‘nulle’. Non so se sono riuscito a
dirlo in modo chiaro…:slight_smile:

Allora mi sto chiedendo, poichè Rails non è in grado di determinare
automaticamente le corrispondenze tra le tabelle - sembra dunque una
formalità definire chiavi esterne - non potrei non segnalare a mysql le
foreign key e nella logica del db definire semplici campi int?

Si, potresti benissimo farlo...infatti, quelli di Rails non sembrano apprezzare molto il database se non come un datastore con un un linguaggio di query, per certi versi, e quindi e progettato proprio
in questo modo.

Sto sbagliando?

Io non butterei via la referential integrity cosi allegramente:-) Comunque, dipende dal progetto... se e una cosa poco importante,
probabilmente non cambia molto se dovessi perdere qualcosa qua o la`.
Se invece gestisci i soldi, sarebbe il caso di usare il database come
un database.


David N. Welton

Linux, Open Source Consulting

Il giorno gio, 31/08/2006 alle 12.27 +0200, Roberto C. ha scritto:

errore:

No?

Sto sbagliando?

Nel penultimo incontro a Roma, abbiamo discusso con Gabriele e un altro
ragazzo (perdono sono una frana con i nomi) sull’effettiva necessita’ di
utilizzare i constraint del database oltre all’astrazione fornita da
activerecord.
Beh dopo una lunga battaglia eravamo tutti concordi sul ‘dipende’ :slight_smile:
In alcuni settori (tipo quello bancario) piu’ livelli di check si
inseriscono e meglio e’, e soprattutto e’ importante non avere valori
‘orfani’.
Sul 99% delle applicazioni web invece questo non e’ un problema
(addirittura software blasonati come drupal partono dal presupposto che
in breve tempo ci si ritrovi con record orfani e fornisce un interfaccia
per ripulirli)

Ergo a meno che di necessita’ particolari, activerecord dovrebbe essere
sufficiente e quindi puoi evitarti di usare innodb :slight_smile:

2006/8/31, Roberto C. [email protected]:

Per determinare l’appartenenza di un utente a un gruppo mi sarei
affidato solamente al campo group_id, e, qualora esso sia 0, l’utente
sarebbe “svincolato”.

è una porcata, ma la dico lo stesso :slight_smile: inserire un gruppo 0
che usi come dummy group ? l’integrità è salva e rails è
felice…


Michele F.
SeeSaw | Another point of view

[email protected]

Grazie per le risposte.

Ecco la mia situazione (tra l’altro a proposito c’è una discussione
attiva).

Ho una tabella groups(id,title…) e una tabella
users(id,username,password,group_id…).

Per determinare l’appartenenza di un utente a un gruppo mi sarei
affidato solamente al campo group_id, e, qualora esso sia 0, l’utente
sarebbe “svincolato”.

A me pare un ragionamento sostanzialmente corretto.

Purtroppo mi trovo in difficoltà perchè le mie conoscenze sui database
sono veramente ridicole.

In definitiva le vostre risposte mi hanno rafforzato l’idea di
“scavalcare” le chiavi esterne.

Ho una tabella groups(id,title…) e una tabella
users(id,username,password,group_id…).

E un utente potrebbe non appartenere a nessun gruppo. Potrebbe
appartenere a piu` gruppi? Io vedrei un ‘join table’ come la
soluzione migliore.


David N. Welton

Linux, Open Source Consulting

Michele F. wrote:

2006/8/31, Roberto C. [email protected]:

Per determinare l’appartenenza di un utente a un gruppo mi sarei
affidato solamente al campo group_id, e, qualora esso sia 0, l’utente
sarebbe “svincolato”.

� una porcata, ma la dico lo stesso :slight_smile: inserire un gruppo 0
che usi come dummy group ? l’integrit� � salva e rails �
felice…

Però dopo mi tocca scrivere del codice in più - in più posti - per
gestire il record falso.

Alla fine io non ho la necessità di avere un database perfettamente
integro… quindi alla fine elimino le costraint che non necessitano di
particolari restrizioni.

ma una foreign key puo essere nulla nella tabella figlia e.g. se hai:

create table groups (
id integer not null,
primary key (id)
) ENGINE=INNODB;

create table users(
id integer not null,
group_id integer
primary key (id),
foreign key (groupd_id) REFERENCES groups(id)
) ENGINE=INNODB;

puoi inserire una row in users con group_id null (devi fare attenzione
che le tabelle siamo InnoDB e che group_id sia nullable).

David W. wrote:

Ho una tabella groups(id,title…) e una tabella
users(id,username,password,group_id…).

E un utente potrebbe non appartenere a nessun gruppo. Potrebbe
appartenere a piu` gruppi? Io vedrei un ‘join table’ come la
soluzione migliore.

ciao David, scusa se mi intrometto ho un problema simile con un db
MySQL… e sono alle primissime armi!
intendi dunque dire fare una terza tabella che raggruppi i “groups_id” e
gli “user_id”? e in pratica come si definirebbe la possibilita’ di un
utente di appartenere a piu’ gruppi?
se tu potessi essere cosi’ gentile da farmi un piccolo esempio…
grazie e scusate ancora l’intromissione!

alcina :slight_smile:

ciao David, scusa se mi intrometto ho un problema simile con un db
MySQL… e sono alle primissime armi!
intendi dunque dire fare una terza tabella che raggruppi i “groups_id” e
gli “user_id”? e in pratica come si definirebbe la possibilita’ di un
utente di appartenere a piu’ gruppi?
se tu potessi essere cosi’ gentile da farmi un piccolo esempio…
grazie e scusate ancora l’intromissione!

In realta, vi consiglio vivamente il libro su Rails (quello originale) perche parla di tutte queste cose. Insomma, oltre ad
imparare qualcosa su Rails, e` interessante da altri punti di vista.

Comunque, avresti una tabella

groups_users

che punta a tutti e due. ‘users’ avra` has_and_belongs_to_many
:groups, e vice versa per groups, con has_and_belongs_to_many :users

A quel punto, potrai fare cose come:

u = User.find 23

u.groups - una lista di tutti i gruppi a cui appartiene l’utente.


David N. Welton

Linux, Open Source Consulting

On Aug 31, 2006, at 12:55 PM, Roberto C. wrote:

sarebbe “svincolato”.
A me pare un ragionamento sostanzialmente corretto.

Se sostituisci 0 con NULL allora si’, e’ corretto :slight_smile:


Stefano C.
[email protected]

David W. wrote:

Ho una tabella groups(id,title…) e una tabella
users(id,username,password,group_id…).

E un utente potrebbe non appartenere a nessun gruppo. Potrebbe
appartenere a piu` gruppi? Io vedrei un ‘join table’ come la
soluzione migliore.

Il mio db ha già una struttura abbastanza complessa.
Cerco di mantenere un po’ di semplicità .

Alla fine non mi cambia il fatto che un utente possa appartenere solo a
un singolo gruppo.

Ruby for Symbian
Ruby for Symbian is a version of the Ruby object orientated scripting
language for Symbian phones. It currently runs on S60 2nd Edition phone
and is available only in a preview release version (intended to
demonstrate different milestones in the project). Ruby for Symbian was
funded by the Google Summer of Code program.

http://ruby-symbian.rubyforge.org/