1

書店のデータベースアプリケーションを作成しようとしています。参照するフィールドがオートインクリメントしているときに、外部キー制約を効率的に模倣するにはどうすればよいですか?

仕様: 「登録後、ユーザーは1つまたは複数の書籍を注文することができます。注文の合計金額は彼/彼女に報告する必要があります。ユーザーは1回以上、 "

合計金額はそれほど悪くはないようです。

オーダー(オーダーID:INT(11)、ログイン名:VARCHAR(45)、日付:DATETIME)

BooksOrdered(オーダーID:INT(11ここ

は、2つの関連テーブルであります)、ISBN:VARCHAR(45)、カウント:INT(11))

太字の項目はPKです。

私たちのデータベースでは、パフォーマンスの問題でFKが許可されていないため、アプリケーション層でそれらを模倣しています。 BooksOrdered.orderIDは本当にFKであり、あまり言及されていません。さらに、Order.orderIDは自動インクリメントです。

私は、新しい注文を挿入する際にorderIDが一致していることを確認しようとしています(外部キー制約を模倣している)。

基本的には、ArrayList(BookOrderは単にISBNとカウントを保持します)を指定して効率的に挿入する方法を理解できません。私が考えてきた

一つの解決策は次のとおりです。

私は単に注文から最大のorderIDをつかむ、BooksOrderedに行を追加するたびに。これは非効率的と思われ、私はそれに他の問題があると思います(同時アクセス/挿入?)。

ですから、私はあなたに質問します。この自動インクリメントFKをどうやって模倣するべきですか?それとも、テーブルを再構築することを提案しますか?

私は魔法のように最後の注文を掴むことができる方法はありますか?私は注文に挿入します...挿入の過程では?

EDITは:

さてさて、私は、次の不完全な機能があります。今

public int orderBooks(String loginName, ArrayList<BookOrder> bookOrders) throws Exception{ 

    int id = -1; 
    //Working on the date situation 
    java.util.Date today = new java.util.Date(); 
    Timestamp sqlDate = new java.sql.Timestamp(today.getTime()); 

    Connector con=null; 
    String query = "INSERT INTO Order (loginName, date) " + 
      " VALUES ('"+loginName+"', "+sqlDate+")"; 
    ResultSet rs; 


    try{ 
     con= new Connector(); 
     con.stmt.executeUpdate(query, Statement.RETURN_GENERATED_KEYS); 
     rs = con.stmt.getGeneratedKeys(); 
     if (rs.next()) { 
      id = rs.getInt(1); 
     } else { 
      throw(new Exception()); // mmm... 
      // throw an exception from here 
     } 
     con.stmt.close(); 
    } catch(Exception e) { 
     System.err.println("Unable to execute query:"+query+"\n"); 
     System.err.println(e.getMessage()); 
     throw(e); 
    } 
    finally 
    { 
     if (con != null) 
     { 
      try 
      { 
       con.closeConnection(); 
      } 
      catch (Exception e) { /* ignore close errors */ } 
     } 
    } 




    return id; 
} 

、私はID = stmt.executeUpdate(クエリ、のStatement.RETURN_GENERATED_KEYS)を置く必要があります;?私はそれを正しい場所に入れましたか? (テスト可能なプロトタイプを構築する作業を続けます)

+4

*私たちのデータベースでは、パフォーマンスの問題でFKが許可されていません "* DBMSは外部キーを使用するように構築されています。 FKs - いくつかの反対意見にもかかわらず.. " –

+3

@シルバー:あなたのデータベース設計者はトレーニングが必要です。彼は幻想的な生活をやめるべきです。なぜマイクロソフト/オラクルがパフォーマンスが低下すると、データベースに外部キーやその他の制約を与えるのかという愚かなミスをしているのですか。 http://goo.gl/HRkj1 http://goo.gl/xl5Uaデザイナーが一度googleする必要がある記事がたくさんあります。 –

+0

ありがとうございます、私は彼に知らせてください。私はFKを使うことができればと思っています。物事をもっと楽にしてくれるでしょう。 –

答えて

0

どの言語を使用していますか?現在のデータベースハンドルから最後に自動インクリメントされた値を取得する機能を持つ可能性があります。たとえばPHPでは、mysql_insert_id()doc)を使用します。 Perl DBIでは、last_insert_id()を使用できます。(DBI Doc

のためには、あなたがのexecuteUpdateにフラグを設定する必要があります。

id = stmt.executeUpdate(query, Statement.RETURN_GENERATED_KEYS); 

stmt.getGeneratedKeys()機能もあります。 See the docs。 executeUpdateエントリはgetGeneratedKeysのすぐ下にあります。

+0

私はJavaを使用していますが、何かを見つけました: "select LAST_INSERT_ID()" そうですか?キンダ? また、多くのユーザーが同時にアクセスすると良いでしょうか? –

+1

あなたはexecuteUpdateを使用していますか? 'numero = stmt.executeUpdate(query、Statement.RETURN_GENERATED_KEYS);' mysqlのlast_insert_id()への2回目の呼び出しを行う方が移植性が高く、効率的です。 – Ilion

+0

ええ私はexecuteUpdateを使用しています。さて、クールな感謝、私はそれを行こう! –

関連する問題