2012-06-24 17 views
7

我正在嘗試創建一個可容納大約1000支槍的槍支網站。這不是很多數據庫條目,但我試圖儘可能保持數據庫的輕量級。我創建了五個表格,記住了標準化,並且我在將數據放入一個查詢中的所有五個表格時遇到了問題。我的數據庫的結構,像這樣:如何使用多個表並且不會獲取重複的數據? (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| 
        +-----------------+ 

這可能過於標準化的,但是這是我與合作;)

讓我告訴代碼:

形式

<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'); 
} 

因此,當我使用上面的代碼添加項目時,一切正常,但是當我使用相同的製造商名稱添加另一個項目時,它將複製它。我只是想讓它意識到它已經存在並且不會重複它。

我在考慮進行一些檢查,看看數據是否已經存在,如果沒有,那麼不要輸入數據,而是獲取id並在需要的地方輸入其他表。

我想到的另一件事是爲最有可能被複制的數據創建一個下拉列表並將該值指定爲id。但是,我的簡單思維無法弄清楚最好的方法:(希望一切都有道理,如果不是的話,我會盡力詳細說明)

回答

1

如果你有一些只有極限數據的領域(口徑肯定是一個,而且我懷疑manfacturer也可以工作),你可以預先填充數據庫中的表格並將其轉化爲查找字段。

在您的HTML表單上,而不是有文本輸入字段,您可以改爲打印出一個選擇框。 select的值是查找字段中的ID - 您不必擔心向數據庫中的查找字段添加任何內容。

當我不得不這樣做時,我寫了一個函數來完成數據插入;它會檢查值是否在表中。如果是,則返回該字段的索引;否則,它將其添加爲新條目,並返回新條目的ID。這不是最優雅的解決方案,但它運作良好。

+0

謝謝安德魯西,我隨你的建議去了。我只是填充唯一數據的選擇字段。我發現的另一件事是,PDO具有內置的功能,就像Ollie爲MySQL提到的那樣,當插入數據時,它會注意到重複條目,並且在拋出定製錯誤時不會完成插入操作。謝謝! – Mike

2

你需要弄清楚構成一個獨特(不重複)型號,類型和口徑。

然後,你需要爲那些執行的唯一表中的唯一索引。見http://dev.mysql.com/doc/refman/5.0/en/create-index.html

例如,你可以使用make_id,模型名稱,並caliber_id唯一標識一個模型。您需要

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

設置您的唯一索引。請注意,主鍵索引可以是唯一索引,但您也可以具有其他唯一索引。

然後您可以使用INSERT ON DUPLICATE KEY UPDATE填充您的表格。在這裏看到:http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html

對於這一切才能正常工作,你必須讓你嘗試之前,填充每個model行存在一定合適typecalibermake行:你的前三個表需要的ID填充第四個。

相關問題