タグを使って本の属性を定義する必要があり、テーブルの作成を考えています
Table Books
Book_Id INT, PK
Book_Name varchar
Table Tags
Tag_Id INT, PK
Tag_Name varchar
本には、ホラー、面白い、暗いなどの複数のタグを含めることができます。本とそのすべてのタグの間の1対多の関係をどのように定義しますか?
タグを使って本の属性を定義する必要があり、テーブルの作成を考えています
Table Books
Book_Id INT, PK
Book_Name varchar
Table Tags
Tag_Id INT, PK
Tag_Name varchar
本には、ホラー、面白い、暗いなどの複数のタグを含めることができます。本とそのすべてのタグの間の1対多の関係をどのように定義しますか?
ブックとタグの間に次のような結合テーブルを作成する必要があります。
Books_Tags Table
Book_id int -- will be PK
Tag_ig int -- will be PK
結合テーブルの主キーは、他のテーブルへの外部キーでもあるフィールド(book_id
と)の両方で構成されます。tag_id
次に、データをクエリする場合、クエリは次のようになります。
select *
from books b
left join books_tags bt
on b.book_id = bt.bookid
left join tags t
on bt.tag_id = t.tag_id
自然キーを使用することを検討してください (サロゲート "タグ ID" ではなく) JOIN の 1 つを避けるために、そうでなければタグを検索するときに必要になります (これは、適度なサイズのデータベースではパフォーマンスが重要なパスになる可能性があります)。
例えば:
CREATE TABLE BOOK (
BOOK_ID INT PRIMARY KEY
-- Other fields...
);
CREATE TABLE BOOK_TAG (
TAG_NAME VARCHAR(30),
BOOK_ID INT,
PRIMARY KEY (TAG_NAME, BOOK_ID),
FOREIGN KEY (BOOK_ID) REFERENCES BOOK (BOOK_ID) ON DELETE CASCADE
);
-- For enforcing and cascading the FK and for GROUP BY (in the query below).
CREATE INDEX BOOK_TAG_IE1 ON BOOK_TAG (BOOK_ID, TAG_NAME);
CREATE TABLE TAG (
TAG_NAME VARCHAR(30) PRIMARY KEY,
-- Other fields...
);
次のように、指定されたタグのいずれかを持つ本を取得できます。
SELECT *
FROM BOOK
WHERE BOOK_ID IN (
SELECT BOOK_ID
FROM BOOK_TAG
WHERE
TAG_NAME = 'tag1'
OR TAG_NAME = 'tag2'
-- Etc...
);
そして、次のような指定されたすべてのタグを持つ本:
SELECT *
FROM BOOK
WHERE BOOK_ID IN (
SELECT BOOK_ID
FROM BOOK_TAG
WHERE
TAG_NAME = 'tag1'
OR TAG_NAME = 'tag2'
-- Etc...
GROUP BY BOOK_ID
HAVING COUNT(TAG_NAME) = 2
);
ご覧のとおり、JOIN は 1 つだけです (ここでは IN と記述)。本を検索するとき (またはタグ名を表示するだけ - ここには表示されていません) に、TAG テーブルと JOIN する必要はまったくありません。
2 番目の JOIN を実行する唯一の理由は、TAG テーブルからこれらの「その他のフィールド」を取得する必要がある場合です。
3 番目のテーブルを作成し、Book > Tags を多対多の関係にします。
そう:
テーブル Books Book_Id INT、PK Book_Name varchar
テーブル タグ Tag_Id INT、PK Tag_Name varchar
テーブル BookTags Id INT、PK Book_Id INT Tag_Id Int