2016-12-08 12 views
1

私はライブラリデータベースを構築していますが、私は1つの特定のことに固執しています。3つのテーブル間の関係を作る正しい方法

私は3つのテーブル:BookCopy,BookLoanおよびMembersを持っています。どうやってそれらの間の関係を作るのかは分かりませんので、メンバーは本(または書籍)を借りることができ、このすべてをデータベースに正しく反映させることができます。

私の考えは、2つの多対多テーブルを持つことだったので、BoakLoansMembersBookCopiesBookLoansを追加しました。私はこれが正しかったかどうかわからないし、たとえそれがあっても、非常に多くのテーブルをどのように作成するかわからない。

今、私はこのケースで何が最善のものになるのだろうと思っています。なぜですか?

enter image description here

+1

あなたは 'BookLoan'に' BookCopyId'や 'MemberId'のようなフィールドを追加する必要があります。 'dateReturned'が' NULL'の場合、それはまだ返されていないことを意味します。それ以外の場合は返されます。 –

+0

日付フィールドにvarcharを使用しないでください。mysqlには 'date'型があります。整数型でなければなりません –

答えて

2

ちょうどメートルを持つことができます。メンバーとBookCopy間メートルの関係を、あなたの相互結合表としてあなたBookLoan表を使用します。ですから、基本的には、テーブルのメンバーとBookcopyから表BookLoanへの参照を追加する必要が

BookLoan 
    --------------- 
    idBookLoan 
    dateLoaned 
    dateReturned 

    idBookCopy FK -- add these two 
    idMember FK 

そしてまた、私は推測しているidBookCopy、idMemberとdateLoanedあなたBookLoanテーブルの主キー

+0

主キーについて知っていない、彼はすでに' idBookLoan'を持っています –

+0

idBookLoanフィールドは、 – DZDomi

+0

'dateLoaned'が日付フィールド(時間なし)の場合、ユニークではない可能性があります...メンバーがチェックアウトした場合、変更されました彼らの心は戻ってきて、再び心を変えて、それを再確認しました。これらのようなエッジケースを回避し、後でローンテーブルを参照することが容易になるのは、合成キーを使用する典型的な理由です。 – Uueerdo

3

を行うことを検討あなたのBookCopyは書籍YのX個のコピーを有することを説明するものであり、その意味で「書籍」は貸し出されていないので、それらの「コピー」は正しいのですか?

私はアクションの最良のコースはおそらくBookLoanテーブルが多対多のテーブルでなければならないと考えていると思います。コピーは一度にメンバーに貸与されてから返されます。 BookLoadは、コピーとメンバーのIDと貸し出し日を持つ必要があります(これはdatetimeフィールドではありませんが、varcharのものでなければなりません)&日付が返されます(貸出日付のようにdatetimeである必要があります。返されていないコピーを表すためにnullableでなければなりません)。また、メンバーが同じコピーを複数回チェックアウトできる可能性があるので、ローンの一意(おそらく自動インクリメント)IDを保持する必要があります。

私はおそらくあなたが当初、販売取引と同様に「ローン」を概念化していたと推測しています。 loanCopiesテーブルが必要で、異なるコピーが別々に返される可能性があるので、ローンでdateReturnedを使用することは望ましくありません。


編集(追加観測):それはコピーのみを使用すると、循環から本をご遠慮したい場合は、それが適切な場合があります(をチェックアウトしているかどうかに基づいている場合

  • isAvailableが冗長かもしれけれども)
  • ISBNウィキペディアに応じて13文字(CHARバンは、いくつかの状況下では、VARCHARより少しより効率的)
  • でmaxes 0
  • 文字列型フィールドを使用するのではなく、コピーが参照できる言語テーブルを検討するとよいでしょう。

編集(再:isAvailable): あなただけ貸し出さないコピーを見つける必要がある場合は、このような単純なクエリでは、あなたが必要とするすべてです。

SELECT * 
FROM BookCopy 
WHERE idBookCopy NOT IN (
    SELECT idBookCopy 
    FROM BookLoan 
    WHERE dateReturned IS NULL 
); 

サブクエリが貸し出さコピーのリストを取得し、NOT INは結果でコピーがそのリストに含まれていない確認します。

コピーが貸し出されないように(破損、破損など)、isAvailable "フラグ"は、そのような機能を追加する簡単な方法です。外部クエリのWHERE条件にAND isAvailable = 1を追加するだけです。

+1

あなたの答えをありがとう。それで、私が理解する限り、あなたは答えた相手が何を提案したのかを示唆しています、そうですか?私のBookLoanテーブルにbookCopyFKとmemberFKを置くだけで、2つの接続テーブルを持たないように、2つの多対多テーブルを(私の初期の考え方のように)持つのではなく、 –

+0

はいあなたは正しい – DZDomi

+0

正確には、ローンはコピーとメンバーの接続テーブルです。 – Uueerdo

関連する問題