1

テーブルOrder

oid  payerName address
1       james    1 brown
2       smith     2  smith

テーブル order_item

oid  type  price
1    AN94  3000
2    AK47  1000

Order_item は Order からの外部として。

oidはテーブルの自動インクリメントですOrderが、order_itemテーブルではそうではありません(それが正しい方法かどうかはわかりません)

両方のテーブルに同時に挿入する挿入ステートメントがあります。order_item oid も自動インクリメントにするのが正しいのだろうか?注文テーブルから oid をコピーする方法が他にないためです。

この小さな問題に対する最善のアプローチは何ですか。

4

3 に答える 3

1

order_itemsテーブルの注文 ID フィールドを にauto_incrementしないでください。ordersテーブルに行を挿入するときに自動生成された ID の値を取得するには、LAST_INSERT_ID()関数を使用します。

に独自のauto_incrementid 列があっても問題ありませんorder_items。場合によっては非常に便利です (たとえば、個々のorder_item行を更新する場合、列の組み合わせではなく、独自の ID で参照できます)

提案されたスキーマは次のようになると言われています

CREATE TABLE orders
(`order_id` int not null auto_increment primary key, 
 `payerName` varchar(5), 
 `address` varchar(8)
);
CREATE TABLE order_items
(`order_item_id` int not null auto_increment primary key, 
 `order_id` int, 
 `type` varchar(4), 
 `price` decimal(19,2),
 foreign key (order_id) references orders (order_id)
);

id 列の名前は、わかりやすくするために、私の例では意図的に名前が変更されています。明らかに自分のものを変更する必要はありません。

次に、注文と注文項目を挿入します

INSERT INTO orders (`payerName`, `address`)
VALUES ('james', '1 brown');

INSERT INTO order_items (`order_id`, `type`, `price`)
VALUES (LAST_INSERT_ID(), 'AN94', 3000);

これがSQLFiddleのデモです


質問で PDO について言及しませんでしたが、それを使用するコードは次のようになります

try {
    $db = new PDO('mysql:host=localhost;dbname=test', 'user', 'userpwd');
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

    //$db->beginTransaction();

    $query=$db->prepare("INSERT INTO orders (`payerName`, `address`) VALUES (?, ?)");
    $query->execute(array('james', '1 brown'));

    $order_id = $db->lastInsertId();

    $query=$db->prepare("INSERT INTO order_items (`order_id`, `type`, `price`) VALUES (?, ?, ?)");
    $query->execute(array($order_id, 'AN94', 3000));

    //$db->commit();
} catch (PDOException $e) {
    echo "Exeption: " .$e->getMessage();
}
$query = null;
$db = null;
于 2013-08-27T02:31:10.147 に答える