任何人都可以解释在设计带有示例的表时如何实现一对一,一对多和多对多关系吗?

评论

您可能还希望阅读这篇文章。...stevencalise.wordpress.com/2010/09/01/…我会密切注意第2点和第3点。

@tsells有时会问您一些问题,这些问题不适用于您简历中的内容或与工作要求直接相关的问题。我得到了要在一家公司面试我的人的清单,其中一个是数据库专家。我的履历表上没有SQL,但我尝试了一些简单的SQL查询。它帮助了我,找到了工作。后来我发现,招聘经理担心求职者在压力下的反应。他们是否承认自己的限制或伪造自己的通过方式?如果他们承认自己的极限,他们会尝试还是放弃太早?

#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 KeyForeign Key

因此,我们可以说子表与Primary Key共享

在上表中,Primary Key表中的id列与post_detailsForeign 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