Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    Problema chiave primaria SQL

    Salve a tutti,
    effettuando i test su una piccola applicazione sql mi sono trovato davanti ad un mezzo casino, credo risolvibile, solo che non riesco a venirne fuori ed avrei bisogno di un consiglio.
    Ve lo illustro:

    codice:
    CREATE TABLE IF NOT EXISTS `fornitori` (
      `id_fornitore` int(11) NOT NULL AUTO_INCREMENT,
      `nome` varchar(255) NOT NULL,
      `cognome` varchar(255) NOT NULL,
      `telefono` varchar(255) NOT NULL,
      `email` varchar(255) DEFAULT NULL,
      `indirizzo` varchar(255) DEFAULT NULL,
      `data` varchar(255) NOT NULL,
      PRIMARY KEY (`id_fornitore`)
    );
    
    CREATE TABLE IF NOT EXISTS `libri` (
      `id_libro` int(11) NOT NULL AUTO_INCREMENT,
      `isbn` varchar(255) NOT NULL,
      `autore` varchar(255) NOT NULL,
      `titolo` varchar(255) NOT NULL,
      `casa_editrice` varchar(255) NOT NULL,
      `anno` varchar(4) NOT NULL,
      `materia` varchar(255) DEFAULT NULL,
      `prezzo` float NOT NULL,
      `venduto` varchar(1) NOT NULL DEFAULT '0',
      `data_vendita` varchar(255) NOT NULL,
      PRIMARY KEY (`id_libro`),
      FULLTEXT KEY `autore` (`autore`,`titolo`)
    );
    
    CREATE TABLE IF NOT EXISTS `libri_fornitore` (
      `id_libri_fornitore` int(11) NOT NULL AUTO_INCREMENT,
      `isbn` varchar(255) NOT NULL,
      `id_fornitore` int(11) NOT NULL,
      `data` varchar(255) NOT NULL,
      PRIMARY KEY (`id_libri_fornitore`)
    );
    Ecco le mie tre tabelle, si tratta della gestione di un archivio di libri/fornitori per un mercatino del libro usato. Ecco il problema: al momento della progettazione, stupidamente, non avevo fatto caso che l'ISBN di un libro non è unico, perchè può capitare che due fornitori distinti portino ciascuno un libro con lo stesso ISBN, e quando questo avviene succede un casino.
    Il problema sarebbe risolvibile cambiando la chiave primaria della tabella Libri, assegnandola a id_libro...se non fosse che id_libro viene assegnata da un Auto Increment...non ho come tirarla fuori al momento dell'inserimento del record nella tabella libri_fornitore.

    codice:
    $data = date("d-m-y - G:i:s");             // 22-09-11 - 21:56:01
    $sql=mysql_query("INSERT INTO libri (id_libro,isbn, autore, titolo, casa_editrice, materia, anno, prezzo, venduto, data_vendita) VALUES ('','$isbn', '$autore', '$titolo','$casa_editrice', '$materia', '$anno', $prezzo, '0', '')");
    $sql2=mysql_query("INSERT INTO libri_fornitore (id_libri_fornitore, isbn, id_fornitore, data) VALUES ('','$isbn', '$code', '$data')");
    Questo è l'inserimento. Come posso ovviare al problema? Avevo pensato di effettuare prima l'inserimento del record nella tabella libri, tirare fuori l'id_libro e poi dopo inserire il record corrispondente nella tabella libri_fornitore...ma non è uno spreco abnorme di risorse? Non è un casino da implementare?
    Consigli?

  2. #2
    Usi WordPress? Joomla? phpBB? Ognuno di questi software crea tantissimi indici su ogni tabella (rendendo più laboriose le insert) e non hanno una sola query che possa avvalersi di questi indici. Non esagero, è così. Qualsiasi cosa tu faccia, ovunque tu clicchi, provochi un carico di lavoro che è almeno un ordine di grandezza superiore a quel che sarebbe se chi programma questi software avesse la minima idea di come funziona MySQL. Eppure, su un sito non solo medio-piccolo ma anche grande (purché non enorme) questo non ha nessuna importanza, le prestazioni sono decenti lo stesso.

    Quindi... no, quello che vuoi fare tu non è uno spreco ABNORME di risorse, è un piccolo spreco

    Comunque:
    * togli id_libro dalla prima insert
    * sostituisci $data con NOW()
    * per avere l'id_libro nella seconda insert, usa LAST_INSERT_ID(). Se vuoi saperne di più su questa funzione guarda la documentazione di MySQL o digita HELP 'last_insert_id'.
    STK/Unit: Unit Test framework per MariaDB
    http://stk.wikidot.com/stk-unit

  3. #3
    Dopo aver fatto alcune prove ho dedotto che non riesco ad ovviare ai problemi perchè il database è già piuttosto popolato e cambiarne l'architettura diventerebbe un casino.
    Ho deciso di fare la seguente cosa.
    Controllo sul db del codice ISBN del libro inserito, se il codice è già presente emette un messaggio di errore ed invita a cambiarlo.
    Sostanzialmente vorrei fare questo:

    SELECT sul DB tutti i record con ISBN = ISBN_inserito
    se ISBN_inserito= ISBN (già presente) -> messaggio di errore e invita a modificarlo,
    altrimenti inserisce regolarmente.
    Ho provato questo codice:

    codice:
    if($isbn==TRUE && $autore==TRUE && $titolo==TRUE && $casa_editrice==TRUE && $materia==TRUE && $anno==TRUE && $prezzo==TRUE)
    {
    //$data = date("d-m-y - G:i:s");             // 22-09-11 - 21:56:01
    
    $test=mysql_query("select * from libri where isbn='$isbn'");
    
    while ($riga = mysql_fetch_array($test)) {
    
    
    
    if($riga['isbn']==$isbn){
    	
    	echo "ISBN Gia' presente in elenco. Modifica ISBN ed inserisci";
    	echo '<input type="button" value="Torna indietro" onClick="javascript:history.back()" name="button" target="lista">';
    
    }
    else{
    
    
    $sql=mysql_query("INSERT INTO libri (id_libro,isbn, autore, titolo, casa_editrice, materia, anno, prezzo, venduto, data_vendita) VALUES ('','$isbn', '$autore', '$titolo','$casa_editrice', '$materia', '$anno', $prezzo, '0', '')");
    $sql2=mysql_query("INSERT INTO libri_fornitore (id_libri_fornitore, isbn, id_fornitore, data) VALUES ('','$isbn', '$code', '$data')");
    
    echo 'Libro inserito con successo
    
    
    
    
    ';
    ?> <input type="button" value="Inserisci un altro libro" onClick="" name="button" >
    <?
    echo'
    ';
    }
    
    }}
    else
    {
    echo 'Tutti i campi sono obbligatori
    
    
    
    
    <input type="button" value="Torna indietro" onClick="javascript:history.back()" name="button" target="lista">';
    }
    Solo che non funziona.
    Qualche consiglio per risolvere il problema?

  4. #4
    se inserisci una data nel db sarebbe molto meglio usare il formato ansi (yyyy-mm-dd hh:mm:ss) ed il campo nel formato datetime ti faciliterebbe di molto ordinamento e ricerca.

    quando verifichi la presenza di un valore gia' esistente in un record userei count(*) poi controllerei se il numero delle righe restituite e' == 1

    lo short tag <? al posto del vero tag <?php e' da tempo abbandonato per la possibile confusione con il tag xml <?xml quindi non <?= ma <?php echo

    il campo isbn esiste anche nella tabella libri_fornitore. Se non controlli potresti avere record duplicati. Se ho ben interpretato la tabella libri ha un record per ogni libro trattato e quindi potrebbero esserci piu' libri identici ma venduti in date diverse oppure venduto si/no oppure acquisiti da diverso fornitore.
    Quindi potrebbero esserci piu' libri con isbn identico. Servirebbe anche avere una quantita' del libro disponibile/presente e questo a prescindere se tale libro ha isbn diverso.

    Naturalmente IMHO ...

    Il silenzio è spesso la cosa migliore. Pensa ... è gratis.

  5. #5
    piero.mac hai ragione su tutto.
    Per il discorso della duplicazione dei record con isbn uguale me ne sono reso conto a cose fatte perchè il debug fatto è stato praticamente inesistente, praticamente è stato un errore di progettazione e allo stato attuale del mercatino non posso più modificare la situazione.
    Quindi ho pensato all'escamotage di fare il controllo sul database, vedere se l'isbn esiste già ed eventualmente cambiarlo con un carattere speciale...altrimenti inserire il libro regolarmente. La data è lì per sbaglio, ereditata dal codice di un'altra pagina (difatti è commentata)...

  6. #6
    Dimenticavo che esiste sempre l'indice UNIQUE che impedisce di inserire doppioni. Genera una segnalazione di errore che andra' ovviamente gestita.

    In un caso simile con indice UNIQUE potresti usare: insert ... on duplicate key update

    http://dev.mysql.com/doc/refman/5.5/...duplicate.html

    Il silenzio è spesso la cosa migliore. Pensa ... è gratis.

  7. #7
    Ho fatto così:
    codice:
    if($isbn==TRUE && $autore==TRUE && $titolo==TRUE && $casa_editrice==TRUE && $materia==TRUE && $anno==TRUE && $prezzo==TRUE)
    {
    
    $test=mysql_query("select count(*) from libri where isbn='$isbn'");
    
    
    if($test==1){
    	
    	echo "ISBN Gia' presente in elenco. Modifica ISBN ed inserisci";
    	echo '<input type="button" value="Torna indietro" onClick="javascript:history.back()" name="button" target="lista">';
    
    }
    else{
    
    
    $sql=mysql_query("INSERT INTO libri (id_libro,isbn, autore, titolo, casa_editrice, materia, anno, prezzo, venduto, data_vendita) VALUES ('','$isbn', '$autore', '$titolo','$casa_editrice', '$materia', '$anno', $prezzo, '0', '')");
    $sql2=mysql_query("INSERT INTO libri_fornitore (id_libri_fornitore, isbn, id_fornitore, data) VALUES ('','$isbn', '$code', '$data')");
    
    echo 'Libro inserito con successo
    
    
    
    
    ';
    ?> <input type="button" value="Inserisci un altro libro" onClick="" name="button" >
    <?
    echo'
    ';
    }
    }
    
    else
    {
    echo 'Tutti i campi sono obbligatori
    
    
    
    
    <input type="button" value="Torna indietro" onClick="javascript:history.back()" name="button" target="lista">';
    }
    Ma inserisce il libro nonostante l'isbn sia già presente...

  8. #8
    $test=mysql_query("select count(*) from libri where isbn='$isbn'");

    if($test==1){

    in $test hai il resource id# oppure false.

    codice:
    $test=mysql_query("select count(*) from libri where isbn='$isbn'");
    
    $row = mysql_fetch_row($test);
    if($row[0] == 1) {

    edit@

    meglio se metti if($row[0] => 1 oppure $row[0] > 0

    potrebbe essercene piu' di uno.... anyway...

    Il silenzio è spesso la cosa migliore. Pensa ... è gratis.

  9. #9
    Originariamente inviato da piero.mac

    edit@

    meglio se metti if($row[0] => 1 oppure $row[0] > 0

    potrebbe essercene piu' di uno.... anyway...
    correggo:

    non => ma

    $a >= $b

    Il silenzio è spesso la cosa migliore. Pensa ... è gratis.

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.