2012-06-24 20 views
7

Sto cercando di creare un sito di armi da fuoco che ospiterà circa 1000 cannoni. Non si tratta di molte voci del database, ma sto cercando di mantenere il database più chiaro possibile. Ho creato cinque tabelle, tenendo presente la normalizzazione, e ho problemi a inserire i dati in tutte e cinque le tabelle in un'unica query. Il mio database è strutturato in questo modo:Come lavorare con più tabelle e non ottenere dati duplicati? (MySQL/PDO)

+-----------------+ +-----------------+ +-----------------+ +-----------------+ 
|  make  + |  model  | |  image  | |  type  | 
+-----------------+ +-----------------+ +-----------------+ +-----------------+ 
| PK | make_id | | PK | model_id | | PK | model_id | | PK | type_id | 
+-----------------+ +-----------------+ +-----------------+ +-----------------+ 
| | make_name | | | make_id | | | image_path | | | type_name | 
+-----------------+ +-----------------+ +-----------------+ +-----------------+ 
        | | type_id | 
        +-----------------+   +------------------+ 
        | | caliber_id |   |  caliber  | 
        +-----------------+   +------------------+ 
        | | model_name |   | PK | caliber_id | 
        +-----------------+   +------------------+ 
        | | cost  |   | | caliber_name| 
        +-----------------+   +------------------+ 
        | | description| 
        +-----------------+ 

Questo potrebbe essere troppo normalizzata, ma questo è quello che sto lavorando con;)

mi permetta di mostrare il codice:

forma

<form action="post" method="addProduct.php" enctype="multipart/form-data"> 
    make: <input type="text" name="make" /> 
    model: <input type="text" name="model" /> 
    type: <input type="text" name="type" /> 
    caliber: <input type="text" name="caliber" /> 
    cost: <input type="text" name="cost" /> 
    desc.: <input type="text" name="description" /> 
    Image: <input type="file" name="image" id="image" /> 
      <input type="submit" name="submit" value="Add Item" /> 
</form> 

addProduct.php

$make  = $_POST['make']; 
$model  = $_POST['model']; 
$type  = $_POST['type']; 
$caliber  = $_POST['caliber']; 
$cost  = $_POST['cost']; 
$description = $_POST['description']; 
$image  = basename($_FILES['image']['name']); 
$uploadfile = 'pictures/temp/'.$image; 
if(move_uploaded_file($_FILES['image']['tmp_name'],$uploadfile)) 
{ 
    $makeSQL = "INSERT INTO make (make_id,make_name) VALUES ('',:make_name)"; 
    $typeSQL = "INSERT INTO type (type_id,type_name) VALUES ('',:type_name)"; 
    $modelSQL = "INSERT INTO model (model_id,make_id,type_id,caliber,model_name,cost,description,) VALUES ('',:make_id,:type_id,:caliber,:model_name,:cost,:description)"; 
    $imageSQL = "INSERT INTO image (model_id,image_path) VALUES (:model_id,:image_path)";  
    try 
    { 
     /* db Connector */ 
     $pdo = new PDO("mysql:host=localhost;dbname=gun",'root',''); 
     /* insert make information */ 
     $make = $pdo->prepare($makeSQL);  
     $make->bindParam(':make_name',$make); 
     $make->execute(); 
     $make->closeCursor(); 
     $makeLastId = $pdo->lastInsertId(); 
     /* insert type information */ 
     $type = $pdo->prepare($typeSQL); 
     $type->bindParam(':type_name',$type); 
     $type->execute(); 
     $type->closeCursor(); 
     $typeLastId = $pdo->lastInsertId(); 
     /* insert model information */   
     $model = $pdo->prepare($modelSQL); 
     $model->bindParam(':make_id',$makeLastId); 
     $model->bindParam(':type_id',$typeLastId); 
     $model->bindParam(':caliber',$caliber); 
     $model->bindParam(':model_name',$model); 
     $model->bindParam(':cost',$cost); 
     $model->bindParam(':description',$description);   
     $model->execute(); 
     $model->closeCursor();   
     $modelLastId = $pdo->lastInsertId(); 
     /* insert image information */ 
     $image = $pdo->prepare($imageSQL); 
     $image->bindParam(':model_id',$modelLastId); 
     $image->bindParam(':image_path',$image); 
     $image->execute(); 
     $image->closeCursor(); 
     print(ucwords($manu)); 
    } 
    catch(PDOexception $e) 
    { 
     $error_message = $e->getMessage(); 
     print("<p>Database Error: $error_message</p>"); 
     exit(); 
    } 
} 
else 
{ 
    print('Error : could not add item to database'); 
} 

Così, quando aggiungo un articolo utilizzando il codice sopra, tutto funziona correttamente, ma quando aggiungo un altro elemento usando lo stesso nome del produttore lo duplicherà. Voglio solo rendermi conto che esiste già e non duplicarlo.

Stavo pensando di inserire qualche tipo di controllo per vedere se quei dati esistono già e se lo fa non inserire i dati, ma ottenere l'id e inserirlo nelle altre tabelle dove richiesto.

Un'altra cosa che ho pensato è stato quello di creare un menu a discesa per i dati che saranno molto probabilmente essere duplicato e assegnare il valore come ID. Ma, la mia mente semplice non riesce a capire il modo migliore per farlo :(Spero che tutto ciò abbia senso, se non cercherò di elaborare.

risposta

1

Se hai campi in cui ci sarà sempre un limite di dati (il calibro è sicuramente uno, e ho il sospetto che anche il gestore funzioni), puoi precompilare le tabelle nel database e trasformarlo in un campo di ricerca

sul modulo HTML, invece di avere un campo di inserimento testo, è possibile stampare una casella di selezione, invece. Il valore della selezione è l'ID nel campo di ricerca, quindi non è necessario aggiungere nulla ai campi di ricerca nel database.

Quando ho dovuto farlo in passato, ho scritto una funzione per inserire i dati; controlla per vedere se il valore è nella tabella. Se lo è, restituisce l'indice del campo; in caso contrario, lo aggiunge come una nuova voce e restituisce l'ID per la nuova voce. Non è la soluzione più elegante, ma funziona bene.

+0

Grazie andrewsi, sono andato con il tuo suggerimento. Ho appena compilato campi selezionati per i dati univoci. Un'altra cosa che ho trovato è che PDO ha funzionalità incorporate, come Ollie menzionata per MySQL, che quando INSERISCI i dati noterà voci duplicate e non completerà l'inserimento generando un errore personalizzato. Grazie! – Mike

2

Devi capire cosa costituisce una marca unica (non duplicata), modello, tipo e calibro.

Quindi, è necessario creare indici univoci per quelle tabelle che applicano l'unicità. Vedere http://dev.mysql.com/doc/refman/5.0/en/create-index.html

per esempio si potrebbe utilizzare make_id, nome_modello, e caliber_id per identificare univocamente un modello. Avresti bisogno di

CREATE UNIQUE INDEX UNIQUEMODEL ON MODEL(make_id, caliber_id, model_name) 

per impostare il tuo indice univoco. Si noti che un indice di chiave primaria può essere un indice univoco, ma è possibile avere anche altri indici univoci.

È quindi possibile utilizzare INSERT ON DUPLICATE KEY UPDATE per popolare le tabelle. Vedi qui: http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html

Per tutto questo funzioni correttamente, dovrete per assicurarsi adeguate type, caliber e make righe esistono prima di provare a compilare ogni model consecutive: è necessario gli ID da quei primi tre tabelle a popolare il quarto.

Problemi correlati