Visualizzazione dei risultati da 1 a 3 su 3
  1. #1
    Utente di HTML.it L'avatar di Marcolino's
    Registrato dal
    May 2003
    residenza
    Udine
    Messaggi
    3,606

    autore-libro-capitoli gestione foreign key

    Salve ragazzi.
    Devo creare un'applicazione che permetta a degli scrittori in erba di scrivere dei libri online; ebbene l'applicazione si appoggia ad un database che deve essere formato così:

    tabella autore (generalità e ovviamente una chiave primaria A_ID)
    tabella libro (titolo del libro e una chiave primaria L_ID)
    capitoli (titolo del capitolo, corpo del capitolo, chiave primaria C_ID)
    una tabella di interscambio delle chiavi primarie che tenga conto delle associazioni tra libri e autori e ovviamente dei capitoli associati al libro.

    ebbene tutto sembra funzionare in principio ma poi tenuto conto che se cancellando un libro dall'elenco venivano effettivamente cancellati tutti i riferimenti all'autore e ai capitoli nella tabella di scambio, però nella tabella dei capitoli questi ovviamente rimangono.
    Ora questo fa si che ogni volta un autore cancelli il suo libro (fatti suoi no?) mi si riempia il database di capitoli senza un riferimento al libro e al suo autore.
    Per cancellarli devo necessariamente fare più query in modo da sapere a quale libro si si riferiscono e cancellarli per "sistemare il casino".
    La strada veloce potrebbe essere quella di realizzare una chiave esterna anche nei capitoli e che punti al libro di riferimento, in modo che leggendo quel riferimento se il libro non esiste più, cancello il capitolo, ma appena ci ho provato il database nemmeno mi si installava dandomi un errore di constrait e riferimenti incrociati.

    questo un estratto dell'installatore del database.
    DROP TABLE IF EXISTS Account;
    CREATE TABLE Account (
    A_Id int NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (A_Id),
    nickname varchar(20) NOT NULL,
    password varchar(40) NOT NULL,
    salt varchar(40) NOT NULL,
    email varchar(63) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

    DROP TABLE IF EXISTS Titolo;
    CREATE TABLE Titolo (
    T_Id int NOT NULL AUTO_INCREMENT,
    A_Id int NOT NULL,
    titolo varchar(255) NOT NULL,
    PRIMARY KEY (T_Id, A_Id),
    FOREIGN KEY (A_Id) REFERENCES Account(A_Id)
    ON DELETE CASCADE ON UPDATE RESTRICT
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

    DROP TABLE IF EXISTS Capitolo;
    CREATE TABLE Capitolo (
    C_Id int NOT NULL AUTO_INCREMENT,
    titolo varchar(255) NOT NULL,
    paragrafo text NOT NULL,
    PRIMARY KEY (C_Id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;


    DROP TABLE IF EXISTS tbl_TitoloCapitolo;
    CREATE TABLE tbl_TitoloCapitolo (
    A_Id int NOT NULL,
    T_Id int NOT NULL,
    C_Id int NOT NULL,
    PRIMARY KEY (A_Id, T_Id, C_Id),
    FOREIGN KEY (A_Id) REFERENCES Account(A_Id)
    ON DELETE CASCADE ON UPDATE RESTRICT,
    FOREIGN KEY (T_Id) REFERENCES Titolo(T_Id)
    ON DELETE CASCADE ON UPDATE RESTRICT,
    FOREIGN KEY (C_Id) REFERENCES Capitolo(C_Id)
    ON DELETE CASCADE ON UPDATE RESTRICT
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
    Qualcuno mi sa aiutare?

  2. #2
    se non ti fa aggiungere la chiave che relaziona capitoli e libri è perché dentro alla tabella dei capitoli avrai ancora dei record non relazionati. per vedere quali sono (ed eventualmente cancellarli) hai bisogno di una query tipo questa

    SELECT * FROM Capitoli TC LEFT JOIN Libri TL ON TC.IdLibro=TL.IdLibro WHERE TL.IdLibro IS NULL

    Tieni presente che non hai bisogno della tabella di interscambio tra Capitoli e Libri, perché un Capitolo può far parte SOLO di un Libro (hai invece correttamente bisogno della tabella di interscambio Autori/Libri perché un Autore può scrivere più Libri e perché un Libro può essere scritto da più Autori). non ho poi capito a cosa serva la tabella tbl_TitoloCapitolo

  3. #3
    Utente di HTML.it L'avatar di Marcolino's
    Registrato dal
    May 2003
    residenza
    Udine
    Messaggi
    3,606
    Originariamente inviato da optime
    se non ti fa aggiungere la chiave che relaziona capitoli e libri è perché dentro alla tabella dei capitoli avrai ancora dei record non relazionati. per vedere quali sono (ed eventualmente cancellarli) hai bisogno di una query tipo questa
    No non me la fa proprio creare, se metto un riferimento al libro in capitoli come chiave esterna in fase di creazione dato che per prima cosa tolgo la tabella se presente mi dice: " Integrity constraint violation: 1217 Impossibile cancellare la riga: un vincolo d'integrita' referenziale non e' soddisfatto "
    Questo accade se modifico la tabella capitoli così:
    DROP TABLE IF EXISTS Capitolo;
    CREATE TABLE Capitolo (
    C_Id int NOT NULL AUTO_INCREMENT,
    T_Id int NOT NULL,
    titolo varchar(255) NOT NULL,
    paragrafo text NOT NULL,
    PRIMARY KEY (C_Id, T_Id),
    FOREIGN KEY (T_Id) REFERENCES Titolo(T_Id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
    In questo caso l'unica soluzione è eliminare la chiave esterna mantenendo comunque il riferimento al libro.

    SELECT * FROM Capitoli TC LEFT JOIN Libri TL ON TC.IdLibro=TL.IdLibro WHERE TL.IdLibro IS NULL

    Tieni presente che non hai bisogno della tabella di interscambio tra Capitoli e Libri, perché un Capitolo può far parte SOLO di un Libro (hai invece correttamente bisogno della tabella di interscambio Autori/Libri perché un Autore può scrivere più Libri e perché un Libro può essere scritto da più Autori). non ho poi capito a cosa serva la tabella tbl_TitoloCapitolo
    tbl_TitoloCapitolo è proprio la tabella dei riferimenti.
    Quello che vorrei evitare in questa applicazione è il proliferare delle query e soprattutto campi che memorizzino valori come "autore1, autore2," oppure "libro1" --> "capitolo1, capitolo2, capitoloX" proprio per evitare di complicarmi la vita in caso l'autore (o gli autori) decidano di cancellare un capitolo.
    Per questo le chiavi esterne e credimi fino a qui funziona pure bene, quello che ora mi preme è fare sì che non mi restino capitoli senza un ibro a cui fare riferimento nel database.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.