English 中文(简体)
SQL表中两个条目之间的关联
原标题:Association between two entries in SQL table

假设您有一个存储人员列表的数据库表。你想在人与人之间建立关系,也就是说,我和J是朋友。

我想在这种情况下,需要第二个表来存储人员关联。该表将包含两个字段(person1,person2),每个条目对应于两个人之间的一对一关系。

这是对的吗?还是有更聪明的方法?此方法使关联表的比例类似于n_users^2。

最佳回答

是的,如果你想建立多对多关系的模型,这是正确的。这就是所有人都可以有许多朋友。

如果你有一对多关系,就像所有人都有一个老板(或没有老板)一样,你不需要额外的表,那么你只需要在个人表中有一个BossId列。

问题回答

1. For one-to-one relationship:

例如表UserInfo(用于用户个人信息)和表UserCredential(用于用户登录信息)。这是为了减少一条记录的大小而进行的表拆分。

为每个表指定相同的主键,并创建从一个(辅助表)到另一个(主表)的外键:

UserInfo(#UserID);
UserCredential(#UserID)
    FOREIGN KEY (UserID) REFERENCES UserInfo(UserID);

前缀为“#”的列是表的主键。

2. For many-to-one relationship:

例如表Employee和表Department。每个员工只属于一个部门,但一个部门可能有零到多个员工。

将Department表的主键列添加到Employee表中,并创建一个从Emp到Dep的FK:

Department(#DepartmentID);
Employee(#EmployeeID, DepartmentID)
    FOREIGN KEY (DepartmentID) REFERENCES Department(DepartmentID);

如果您经常需要使用Employee.DepartmentID列进行查询,可以在其上创建索引:

CREATE INDEX IX_Employee_DepartmentID ON Employee(DepartmentID);

3. For many-to-many relationship:

例如表User及其自身。一个用户可以与另一个用户成为朋友,并且友谊是双向的(A是B的朋友,所以B也是A的朋友)。一个用户可以跟随另一个用户,但以下是单向的(a跟随B,但B不能同时跟随a)。在图论中,友谊是一个无向图,下面是一个有向图。

需要单独的表格来表示多对多关系:

User(#UserID);
Friendship(#LeftUserID, #RightUserID)
    FOREIGN KEY (LeftUserID) REFERENCES User(UserID)
    FOREIGN KEY (RightUserID) REFERENCES User(UserID)
    CHECK (LeftUserID < RightUserID);
Following(#LeftUserID, #RightUserID)
    FOREIGN KEY (LeftUserID) REFERENCES User(UserID)
    FOREIGN KEY (RightUserID) REFERENCES User(UserID)
    CHECK (LeftUserID <> RightUserID);

表Friendship和Following都使用组合主键(有两列或多列)。

友谊表中的检查约束禁止以下记录:

  • (A,A): one should not be a friend of oneself.
  • (B,A): for the friendship between A and B, the record (A,B) is enough. This is a case of the DRY principle.

表Following中的检查约束仅禁止类似(A,A)的记录。(A,B)表示A在B之后,(B,A)表示B在A之后,这两个记录的含义不同,因此两者都是必要的。

您可以创建额外的索引来优化第二列的查询(假设PK是聚集索引):

CREATE UNIQUE INDEX IX_Friendship_Right_Left
    ON Friendship(RightUserID, LeftUserID);
CREATE UNIQUE INDEX IX_Following_Right_Left
    ON Following(RightUserID, LeftUserID);

你可能还想建立这种类型的关系。在这种情况下,最好使用两个表,RelationshipTypes和Relationships。唯一键可以位于所有3个Relationship字段上。

Relationships
  PersonId
  RelatedPersonId
  RelationshipTypeId

RelationsShipTypes
  Id
  Name




相关问题
what is wrong with this mysql code

$db_user="root"; $db_host="localhost"; $db_password="root"; $db_name = "fayer"; $conn = mysqli_connect($db_host,$db_user,$db_password,$db_name) or die ("couldn t connect to server"); // perform query ...

Users asking for denormalized database

I am in the early stages of developing a database-driven system and the largest part of the system revolves around an inheritance type of relationship. There is a parent entity with about 10 columns ...

Easiest way to deal with sample data in Java web apps?

I m writing a Java web app in my free time to learn more about development. I m using the Stripes framework and eventually intend to use hibernate and MySQL For the moment, whilst creating the pages ...

join across databases with nhibernate

I am trying to join two tables that reside in two different databases. Every time, I try to join I get the following error: An association from the table xxx refers to an unmapped class. If the ...

How can I know if such value exists in database? (ADO.NET)

For example, I have a table, and there is a column named Tags . I want to know if value programming exists in this column. How can I do this in ADO.NET? I did this: OleDbCommand cmd = new ...

Convert date to string upon saving a doctrine record

I m trying to migrate one of my PHP projects to Doctrine. I ve never used it before so there are a few things I don t understand. In my current code, I have a class similar to this: class ...

热门标签