2016-10-28 11 views
0

2つのMySQLテーブルがあります(これらは粗いテーブルです)LocationはDeliveryの複数値属性なので、自分のテーブル外部キーのIDとして変数を使用して2つのテーブルにデータを挿入

CREATE TABLE `Delivery` (
    `Date` varchar(10) NOT NULL, 
    `Time` varchar(10) NOT NULL, 
    `OrderTotal` float NOT NULL, 
    `DeliveryID` int(11) PRIMARY KEY AUTO_INCREMENT , 
    `Tip$` float NOT NULL, 
    `Username` varchar(50) NOT NULL 
) 

そして

CREATE TABLE `Location` (
    `DeliveryID` int(10) NOT NULL, 
    `APT` varchar(10) DEFAULT NULL, 
    `Street` varchar(50) NOT NULL, 
    `Address` int(20) NOT NULL, 
) FOREIGN KEY ('DeliveryID') REFERENCES `Delivery` (`DeliveryID`); 

だから私は何をしたい私は、自身のそれぞれのデータと配信に挿入、および配信に独自のマッチングIDでロケーションテーブルにデータを追加すると言っています明らかに。多値属性をそれぞれのテーブルに分割するように言われました。それでは、私がやっていることは

INSERT INTO Delivery 
VALUES (DEFAULT, '12345','10:53am','admin','100','10'); 

SELECT @Var := Last_INSERT_ID(); 

INSERT INTO Location 
VALUES (@Var, '1234','address',DEFAULT); 

である私の質問は、この悪い習慣はありますか?または、これを回避する方法はありますか?その中にすべてのロケーションデータが含まれているより大きなDeliveryテーブルを持つだけですか?私の恐れは、どういうわけか、このデータベースの複数のユーザーが何らかの方法でDeliveryテーブルに挿入して、テーブルからMAX(DeliveryID)を取得するのに0.0005秒で同期できなくなるということです。このサイズのプロジェクトでは問題ではないことは分かっていますが、これが大規模なプロジェクトであれば、私が言及したようにエラーが発生する可能性がありますか?

+2

'SET @ Var = LAST_INSERT_ID();'を使用できますか? –

+0

私はそれを変更しました。MAX(ID)を使用する場合と同じ結果が得られます。 – Dringo

答えて

0

代わりに、最後に挿入されたID(https://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_last-insert-id)を使用する必要があります。 MAX()で余分な選択を行う前にあなたのメソッドに遭遇したことはありませんでした。そうすれば、そのアプローチで間違ったIDを取得する可能性があります。

+0

Last_INSERTED_ID()を使用すると、多かれ少なかれ安全になりますか?または、完璧な方法は、Address、street、APT#をDelivery Tableに投げるだけですか? – Dringo

+0

はい、より安全で使いづらいです。 mysqlによると、 "生成されたIDは接続ごとにサーバに保持されています。つまり、関数が特定のクライアントに返す値は、AUTO_INCREMENTカラムに影響を与える最も最近の文に対して生成された最初のAUTO_INCREMENT値です。この値は、他のクライアントの影響を受けることはありません。たとえ、自身のAUTO_INCREMENT値が生成されたとしても、この値は他のクライアントの影響を受けることなく、ロックやトランザクションを必要とせずに" – georaldc

+0

phpとmysqlと最後に挿入されたIDでiffyの動作が気付いたのは1回あり、phpのPDOを使用して、挿入クエリの後にSELECTクエリを実行すると、最後に挿入されたID(INSERT - >ランダム選択 - > SELECT last_insert_id())。あなたは何らかの理由で0になります。今では私が使用していたフレームワークなのかもしれませんが、私にとってはそれほど重要なケースではありませんでした。 – georaldc

2

LAST_INSERT_ID()は、セッションごとにメンテナンスされているため、使用する方がはるかに優れています。 セッションは引き続き共有できますが、テーブルから最大キーを取得することは間違いなく危険です。

あなたが同じテーブルに挿入する複数のセッションを持っている場合、あなたは確かにMAX(に問題があるでしょう)

LAST_INSERT_ID()は唯一の自動インクリメントのキーのために働くことを覚えておいてください。

代わりの方法は、アイテムを一意であると特定するすべての基準に一致する配信テーブルから最後のアイテム(delivery_id descによる注文)を選択することです。ユーザー名、日付、注文合計。その後、レコードが正常に作成され、正しいIDを持っているという確信を得ることができます。

また、プライマリキーをロケーションテーブルに追加することをお勧めします。

+0

はい、 'order byは' max() 'を使うよりも安全です – Rahul

関連する問題