2

私は自分の学校の図書館アプリケーションを設計しています。2〜3の主要な図書館があり、一部の部門には独自の図書館があります。これらのクエリが正しいように見えるかどうか知りたいですか?

Libraries 
ID Name
1  Walter
2  Wally
3  Maths dept library

Books
ID Book ID  BookName
1   1       Fundamentals of calculus
2   1       Mechanics 
3   2       Fundamentals of calculus
4   2       Biology

Lib_Book_LookUp
ID  libId bookId
1    1     1
2    1     2
3    2     1
4    2     2

私が解決したい2つの質問は次のとおりです。

  1. 特定の本のコピーがいくつ存在するかを調べます
  2. 特定の本を持っている図書館を探す

これが私が持っているものです:

Select count(Book.bookId) where book.name = "Fundamentals of calculus";

Select count(libId) from Lib_Book_lookUp, Book where Book.BookId = Lib_Book_lookUp.bookId groupBy(libId)

これらのクエリに関する私の質問:

  1. 別のルックアップテーブルを用意し、libIdをBooksテーブルにマージして、bookテーブルの外部キーとして使用する必要はないように思われますか?
  2. クエリは正しいように見えますか?
4

3 に答える 3

4

FROM最初のクエリに句がありません。することもできますがCOUNT(*)、この場合は特に重要ではありません。

 SELECT count(Book.bookId) FROM Books WHERE BookName = "Fundamentals of calculus";

どの図書館に特定の本があるかを見つけるために、COUNT()集合体は必要ありません。WHERE代わりに、結合を含む句が必要です。は、本を持っている図書館の数COUNT()を教えてくれますが、どの図書館を持っているかはわかりません。そのためには、を返すクエリが必要ですLibraries.Name

SELECT
  /* Return library names */
  Libraries.Name
FROM 
  Libraries 
  /* Join through your lookup table to match a book name to a library name */
  JOIN Lib_Book_LookUp ON Libraries.ID = Lib_Book_LookUp.libId
  JOIN Books ON Books.ID = Lib_Book_LookUp.bookId
/* Which book to search for */
WHERE Books.BookName = 'Fundamentals of calculus'

Booksルックアップテーブルは、複数のライブラリに存在する場合に、ブックをテーブル内の1つのレコードに正規化できるため適切です。Booksあなたがそれを持っているので、テーブルに複数のコピーを持っている本当の理由はありません、そしてBook ID列の理由もありません。実際、このBook IDコラムはそのままではかなり誤解を招く恐れがあります。同じIDを持つ2つの異なるタイトルの本があります1

表は実際には次のようになります。Books本のタイトルごとに1つのレコードがあります(タイトルを権限として想定し、ISBNのような実際の権威あるものを忘れています)

Books
ID BookName
1  Fundamentals of calculus
2  Mechanics 
3  Biology

各図書館で各本の複数のコピーが可能な場合は、1部あたりの本を、図書館のバーコードで識別するテーブルに正規化することを検討してください。次に、それらのIDを所蔵としてライブラリに一致させます。

Books (defines bibliographic details)
ID BookName
1  Fundamentals of calculus
2  Mechanics 
3  Biology

Book_Copies (Matches Books.ID to barcode, barcode is Primary Key)
BookId Barcode
1      1234567
1      1234568
2      8654321
2      8654322

Lib_Book_LookUp (matches book copies to libraries, allowing multiple copies by barcode)
ID  libId bookBarcode
1    1     1234567
2    1     1234568
3    2     8654321
4    2     8654322

たとえば、ライブラリごとの本ごとの部数を照会するには、次を使用します。

SELECT 
  Libraries.Name,
  Books.BookName,
  COUNT(*)
FROM 
  Libraries
  JOIN Lib_Book_LookUp ON Libraries.ID = Lib_Book_LookUp.libId
  JOIN Book_Copies ON Lib_Book_Lookup.bookBarcode = Book_Copies.Barcode
  JOIN Books ON Book_Copies.BookId = Books.ID
GROUP BY 
  Libraries.Name, 
  Books.BookName
于 2012-10-15T13:54:40.820 に答える
1

データベースの設計に関しては、ルックアップテーブルに代理キーを設定する必要はありません。ライブラリの複合主キーを実行して、次のように予約するだけです。

Lib_Book_LookUp
libId bookId
1 1
1 2
2 1
2 2

私はあなたの本のIDで次の変更を行いました(力学と生物学は同じIDを持っていました):

本
IDブックIDブック名
11微積分の基礎
22力学
31微積分の基礎
43生物学

最初のクエリでは、ステートメントが参照するテーブルを指定しません(FROM books):

SELECT COUNT(bookId)
FROM books                                       <= Table Reference
WHERE BookName = "Fundamentals of calculus";

2番目のクエリでは、暗黙の構文を使用してテーブルを結合しています。次のように明示的な結合を練習する必要があります。

SELECT Lib_Book_LookUp.libId, Libraries.Name
FROM Lib_Book_LookUp
INNER JOIN Libraries ON Libraries.ID = Lib_Book_LookUp.libId
WHERE bookId IN 
    (SELECT DISTINCT bookId
    FROM books
    WHERE BookName = "Fundamentals of calculus")

Librariesこのクエリはとテーブルを結合し、検索対象の本Lib_Book_LookUpのを持っているライブラリをbookId検索します。

実際に見てください

于 2012-10-15T14:12:36.803 に答える
-1

あなたの本のテーブルは、「本のインスタンス」テーブルのように見えます。そのため、本の名前を付けるべきではありません。それか、BookID列が不要です。

1988年からSQLを記述している場合、2番目のクエリは正しいです。そうでない場合は、join構文を使用する必要があります。

于 2012-10-15T13:56:15.987 に答える