【发布时间】:2011-11-09 22:38:42
【问题描述】:
谁能解释一下在设计表格时如何通过一些示例来实现一对一、一对多和多对多的关系?
【问题讨论】:
标签: sql database-design foreign-keys relational-database relationship
谁能解释一下在设计表格时如何通过一些示例来实现一对一、一对多和多对多的关系?
【问题讨论】:
标签: sql database-design foreign-keys relational-database relationship
一对一:对引用的表使用外键:
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) 中的同一行相关联。
一对多:在关系的多端使用外键链接回“一”端:
teachers: teacher_id, first_name, last_name # the "one" side
classes: class_id, class_name, teacher_id # the "many" side
多对多:使用联结表 (example):
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
【讨论】:
address 的情况下查找student。跨度>
student_classes 行将有2 个一对一 关系,对吧?一个student 行有很多班级,一个classes 行有很多学生——但一个student_classes 行每个人只有一个(?)。
student_classes 行应该只有一个一对一的关系。如果studentA 在classA 和classB 中,那么student_classes 中应该有两行,一行代表什么关系。
以下是关系类型的一些真实示例:
当且仅当表 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);
当且仅当表 A 中的一条记录是一对多的关系 与表 B 中的一条或多条记录相关。但是,表 B 中的一条记录不能与表 A 中的多条记录相关。
要建立一对多关系,表 A(“one”表)的主键必须是表 B(“many”表)的辅助键。
例如:
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
);
当且仅当表 A 中的一条记录与表 B 中的一条或多条记录相关时,关系是多对多的,反之亦然。
要建立多对多关系,请创建名为“ClassStudentRelation”的第三个表,该表将具有表 A 和表 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)
);
【讨论】:
一对多的表关系如下:
在关系数据库系统中,一对多表关系基于子表中的 Foreign Key 列链接两个表,该列引用父表行的 Primary Key。
在上面的表格图中,post_comment 表中的post_id 列与post 表id Primary Key 列有Foreign Key 关系:
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。
在上表图中,post_details 表中的id 列与post 表idPrimary Key 列也有Foreign Key 关系:
ALTER TABLE
post_details
ADD CONSTRAINT
fk_post_details_id
FOREIGN KEY (id) REFERENCES post
多对多表关系如下:
在关系数据库系统中,多对多表关系通过一个子表链接两个父表,该子表包含两个引用两个父表的Primary Key 列的Foreign Key 列。
在上面的表格图中,post_tag 表中的post_id 列与post 表id Primary Key 列也有Foreign Key 关系:
ALTER TABLE
post_tag
ADD CONSTRAINT
fk_post_tag_post_id
FOREIGN KEY (post_id) REFERENCES post
并且,post_tag 表中的tag_id 列与tag 表ID Primary Key 列具有Foreign Key 关系:
ALTER TABLE
post_tag
ADD CONSTRAINT
fk_post_tag_tag_id
FOREIGN KEY (tag_id) REFERENCES tag
【讨论】:
一对一 (1-1) 关系: 这是主键和外键之间的关系(与外键相关的主键只有一条记录)。这是一对一的关系。
一对多 (1-M) 关系: 这也是主键和外键之间的关系,但这里的主键与多条记录相关(即表 A 有书籍信息,表 B 有多个出版商的一本书)。
多对多(M-M):多对多包括两个维度,下面用示例进行充分解释。
-- 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
)
【讨论】: