#1 楼
一对一:使用外键指向被引用的表: student: student_id, first_name, last_name, address_id
address: address_id, address, city, zipcode, student_id # you can have a
# "link back" if you need
您还必须对外键列(
addess.student_id
)施加唯一约束,以防止子表(address
)中的多行与引用表(student
)中的同一行相关。-many:在关系的许多方面使用外键链接回“一个”侧:
teachers: teacher_id, first_name, last_name # the "one" side
classes: class_id, class_name, teacher_id # the "many" side
多对多:使用联结表(示例):
student: student_id, first_name, last_name
classes: class_id, name, teacher_id
student_classes: class_id, student_id # the junction table
示例查询:
-- Getting all students for a class:
SELECT s.student_id, last_name
FROM student_classes sc
INNER JOIN students s ON s.student_id = sc.student_id
WHERE sc.class_id = X
-- Getting all classes for a student:
SELECT c.class_id, name
FROM student_classes sc
INNER JOIN classes c ON c.class_id = sc.class_id
WHERE sc.student_id = Y
评论
在一对一关系中“反向链接”何时有用的一个很好的例子是什么?感谢您简洁明了的回答。
– dev_feed
2014年5月29日15:32
@dev_feed在数据库设计方面,我认为返回链接没有好处,但是使用上面的示例可以返回给定地址的学生,从而简化查找学生的工作。
–避风港
2014年9月6日23:23
@NullUserException我们是否需要3个表用于多对多关系。不能通过两个表进行多对多关系。
–user2166164
15年5月23日在12:57
@Cody每一个student_classes行应只有一对一的关系。如果studentA在classA和classB中,则student_classes中应该有两行,其中一行与之相关。
– NullUserException
2015年7月6日在16:59
在一对一关系中,联接字段在两个表中都应该是唯一的。它可能在一个表上保证了唯一性,但它可能需要在另一张表上具有唯一索引的PK。
–HLGEM
16年4月14日在18:54
#2 楼
以下是关系类型的一些实际示例:一对一(1:1)
关系是一对一的,当且仅当如果表A中的一条记录最多与表B中的一条记录相关。
要建立一对一关系,表B的主键(无孤立记录)必须为表A的辅助键(带有孤立记录)。
例如:
CREATE TABLE Gov(
GID number(6) PRIMARY KEY,
Name varchar2(25),
Address varchar2(30),
TermBegin date,
TermEnd date
);
CREATE TABLE State(
SID number(3) PRIMARY KEY,
StateName varchar2(15),
Population number(10),
SGID Number(4) REFERENCES Gov(GID),
CONSTRAINT GOV_SDID UNIQUE (SGID)
);
INSERT INTO gov(GID, Name, Address, TermBegin)
values(110, 'Bob', '123 Any St', '1-Jan-2009');
INSERT INTO STATE values(111, 'Virginia', 2000000, 110);
一对多(1:M)
当且仅当表A中的一条记录与表B中的一个或多个记录相关时,关系才是一对多的。但是,表B中的一条记录不能相关若要建立表A中的多个记录。
要建立一对多关系,表A的主键(“一个”表)必须是表B的辅助键( “许多”表)。
例如:
CREATE TABLE Vendor(
VendorNumber number(4) PRIMARY KEY,
Name varchar2(20),
Address varchar2(20),
City varchar2(15),
Street varchar2(2),
ZipCode varchar2(10),
Contact varchar2(16),
PhoneNumber varchar2(12),
Status varchar2(8),
StampDate date
);
CREATE TABLE Inventory(
Item varchar2(6) PRIMARY KEY,
Description varchar2(30),
CurrentQuantity number(4) NOT NULL,
VendorNumber number(2) REFERENCES Vendor(VendorNumber),
ReorderQuantity number(3) NOT NULL
);
多对多(M:M)
当且仅当表A中的一条记录与t相关时,关系才是多对多的o表B中的一个或多个记录,反之亦然。
要建立多对多关系,请创建第三个表“ ClassStudentRelation”,该表将具有表A和B的主键表B.
CREATE TABLE Class(
ClassID varchar2(10) PRIMARY KEY,
Title varchar2(30),
Instructor varchar2(30),
Day varchar2(15),
Time varchar2(10)
);
CREATE TABLE Student(
StudentID varchar2(15) PRIMARY KEY,
Name varchar2(35),
Major varchar2(35),
ClassYear varchar2(10),
Status varchar2(10)
);
CREATE TABLE ClassStudentRelation(
StudentID varchar2(15) NOT NULL,
ClassID varchar2(14) NOT NULL,
FOREIGN KEY (StudentID) REFERENCES Student(StudentID),
FOREIGN KEY (ClassID) REFERENCES Class(ClassID),
UNIQUE (StudentID, ClassID)
);
评论
第一个示例:GID号(6)和SGID号(4),为什么? SGID也应该不是(6)吗?第二个例子是number(4)和number(2)...
–obeliksz
18/12/7在11:02
@obeliksz可以为空吗?
– o牛
18/12/18在8:36
为什么在M:N的末尾使用UNIQUE(StudentID,ClassID)?
– strix25
19年4月16日在9:43
@ strix25为了避免在多次创建相同的ClassStudentRelation行时重复进行操作,因为如果您不确定外键StudentID和ClassID都是唯一的,那么什么会停止创建具有相同StudentID和ClassID的新行呢?因为它们在上面的代码中不是唯一的。因此,您可以像上面的代码一样实现它,或者添加一个包含StudentID和ClassID的主键,以避免重复在ClassStudentRelation中创建同一行。
–Fouad Boukredine
19年5月4日在19:18
@valik数据库中的数据通过引用现有数据而不是多次创建同一数据来工作,为什么要这样做?当然您不必这样做,否则效率不高。考虑到这一点,让我们回到您的示例(詹姆斯有生物学而生物学有詹姆斯),当然可以,但是无需创建数据库中已经存在的另一条数据。您需要做的就是在您要创建任何关系时仅引用已经存在的关系。希望对您有所帮助:)
–Fouad Boukredine
19年7月11日在23:09
#3 楼
这是一个非常常见的问题,所以我决定将这个答案变成一篇文章。
一对多
对多表关系如下所示:
在关系数据库系统中,一对多表关系基于两个表之间的
Foreign Key
列链接在上表中,
Primary Key
表中的post_id
列与post_comment
表ID Foreign Key
列具有post
关系:ALTER TABLE
post_comment
ADD CONSTRAINT
fk_post_comment_post_id
FOREIGN KEY (post_id) REFERENCES post
一对一
一对一的表关系如下:
在关系数据库系统中,一对一的表关系基于子级中的
Primary Key
列链接两个表,该列也是引用父表行的Primary Key
的Foreign Key
。因此,我们可以说子表与
Primary Key
共享在上表中,
Primary Key
表中的id
列与post_details
表Foreign Key
post
列也具有id
关系: > 多对多
多对多表关系如下所示:
在关系中数据库系统中,多对多表关系通过一个子表链接两个父表,该子表包含两个
Primary Key
列,这些列引用两个父表的Foreign Key
列。在上表中,
Primary Key
post_id
表中的列与post_tag
表ID也存在Foreign Key
关系,即post
列:ALTER TABLE
post_details
ADD CONSTRAINT
fk_post_details_id
FOREIGN KEY (id) REFERENCES post
Primary Key
表中的tag_id
列与post_tag
表ID Foreign Key
列:ALTER TABLE
post_tag
ADD CONSTRAINT
fk_post_tag_post_id
FOREIGN KEY (post_id) REFERENCES post
#4 楼
一对一(1-1)关系:这是主键与外键之间的关系(与外键相关的主键只有一个记录)。这是一对一的关系。
一对多(1-M)关系:
这也是主键和外键关系之间的关系,但是这里的主键涉及多个记录(即表) A具有图书信息,表B具有一本书的多个出版商。)
多对多(MM):多对多包括两个维度,下面将通过示例进行全面说明。
-- This table will hold our phone calls.
CREATE TABLE dbo.PhoneCalls
(
ID INT IDENTITY(1, 1) NOT NULL,
CallTime DATETIME NOT NULL DEFAULT GETDATE(),
CallerPhoneNumber CHAR(10) NOT NULL
)
-- This table will hold our "tickets" (or cases).
CREATE TABLE dbo.Tickets
(
ID INT IDENTITY(1, 1) NOT NULL,
CreatedTime DATETIME NOT NULL DEFAULT GETDATE(),
Subject VARCHAR(250) NOT NULL,
Notes VARCHAR(8000) NOT NULL,
Completed BIT NOT NULL DEFAULT 0
)
-- This table will link a phone call with a ticket.
CREATE TABLE dbo.PhoneCalls_Tickets
(
PhoneCallID INT NOT NULL,
TicketID INT NOT NULL
)
评论
如果您还添加了主键和外键约束,那会更好更好。
– Ashish K Gupta
17年7月13日在9:55
评论
您可能还希望阅读这篇文章。...stevencalise.wordpress.com/2010/09/01/…我会密切注意第2点和第3点。@tsells有时会问您一些问题,这些问题不适用于您简历中的内容或与工作要求直接相关的问题。我得到了要在一家公司面试我的人的清单,其中一个是数据库专家。我的履历表上没有SQL,但我尝试了一些简单的SQL查询。它帮助了我,找到了工作。后来我发现,招聘经理担心求职者在压力下的反应。他们是否承认自己的限制或伪造自己的通过方式?如果他们承认自己的极限,他们会尝试还是放弃太早?