我在Postgres中有一个图书数据库,我想添加一个authorId列,但是当一本书有很多作者时,我不知道如何使它工作。
作者表
#rename the IIS directory
$renamed = $false
if($success -and $status.value -eq "Stopped")
{
Write-Host ("renaming " + $stagingPath)
try
{
Rename-Item -Path $stagingPath -NewName $tempPath -ErrorAction Stop
}
catch
{
Write-Host("An error occurred during renaming. Retrying ...")
Start-Sleep -s 10
Rename-Item -Path $stagingPath -NewName $tempPath -Force -ErrorAction Stop
}
if(Test-Path $tempPath)
{
$renamed = $true
Get-ChildItem
Write-Host("IIS site renamed to " + $tempPath)
}
else
{
Write-Host("ERROR: Renaming to temp failed")
}
}
书桌
authorId firstName lastName
1 Terry Pratchett
2 Neil Gaiman
我如何使其工作?我的第一个想法是将authorId作为数组存储。
我想要的查询看起来像这样
bookId name authorId
1 Good Omens 1, 2
它会返回这个
SELECT firstName, lastName
FROM author
WHERE authorId IN
(SELECT authorId
FROM book
WHERE bookId=1);
但是我有一种感觉,它是行不通的,并且有更好的方法来实现它。
答案 0 :(得分:1)
教科书解决方案将是拥有一个额外的“映射”表来映射书籍和作者。这样,作者可以创作几本书,而一本书中可以有几位作者:
CREATE TABLE book_authors (
author_id INT NOT NULL,
book_id INT NOT NULL,
PRIMARY KEY book_authors_pk (author_id, book_id),
FOREIGN KEY author_fk (author_id) REFERENCES authors (author_id),
FOREIGN KEY book_fk (book_id) REFERENCES books (book_id)
)
然后,您可以使用join
来查询一本书的作者:
SELECT first_name, last_name
FROM authors a
JOIN book_authors ba on a.author_id = ba.author_id
WHERE book_id = 1
或者,如果您没有该书的ID,则可以使用另一个books
连接来查询其详细信息:
SELECT first_name, last_name
FROM authors a
JOIN book_authors ba ON a.author_id = ba.author_id
JOIN books b ON ba.book_id = b.book_id
WHERE b.name = 'Good Omens'
答案 1 :(得分:0)
m:n关系(一位作者可以写很多书+一本书可以被很多作者写)最好用桥表来建模:
查询以获取书#1的作者:
select first_name, last_name
from author
where author_id in (select author_id from book_author where book_id = 1);
答案 2 :(得分:0)
是的,使用postgres的事实为您提供了一个很好的选择,可以将authorIds存储为数组。您可以像这样定义表:
CREATE TABLE Book (
bookId serial not null,
name varchar,
authorIds int[]
);
您选择的查询应该是
SELECT firstName, lastName
FROM author
WHERE authorId IN
(SELECT unnest(authorIds)
FROM Book
WHERE bookId = 1);