2017-08-04 64 views
1

对于一个学校学科,我必须制作一个具有不同类型关系的小应用程序:一对一,一对多,多对多。数据库设计:从单个表格到一对一的关系?

如果例如来自同一个表'用户'的2个用户ID之间的关系状态(与/关系结婚)仍然是一对一关系?

例如:

表1: '用户'

USER_ID(PK)|用户名|密码| date_registered

表2: '关系'

user_one_id(FK)| user_two_id(FK)|状态

这是一对一数据库的正确示例,还是它本身必须是连接2个表与外部表之间的连接?

+0

尽你所能。我一直在这样做,我从来没有见过一对一的关系是合适的情况。然而,你的情况似乎是学术的,这意味着它不一定代表现实生活。对于你的问题中的例子,问问你自己,你的数据模型是如何处理关系结束的。 –

回答

2

简短的回答并不是真的。

一对一关系是您在建立两个表的主键之间的关系时得到的。

以你的想法:说我们有一堆的用户,但我们在这样一个表来跟踪他们的登录信息:

CREATE TABLE users (
    user_id int NOT NULL PRIMARY KEY, 
    username varchar, 
    password varchar); 

而另一个表是这样的:

CREATE TABLE user_personal(
    user_id int NOT NULL PRIMARY KEY, 
    age int, 
    firstname varchar, 
    lastname varchar) 

一旦创建了这两个表格,很容易看到每个表格中都有一列具有相同数据类型(user_id)的列,该列用作该表的主键。

如果您使用user_id作为键在两个表之间建立关系,则您建立了一对一关系,因为user_id只能在任一表中出现一次。

这看起来有点不可思议,因为您可能会问为什么要将数据分离出来。为什么要在一个表中包含哪些数据字段而不是另一个表中区分?一个简单的解决方案是数据隔离。说我们修改第二个表显示此:

CREATE TABLE user_personal(
    user_id int NOT NULL PRIMARY KEY, 
    age int, 
    firstname varchar(255), 
    lastname varchar(255), 
    home_address varchar(255), 
    social_security_number int) 

我们可能想给访问一些数据的一些人,而不是其他人。如果你有你的用户关系表,可能很好地向一些人展示人与人之间的家庭/友谊关系,但你不想放弃他们的社会安全号码和家庭住址。您可能会将数据分离出来的另一个重要原因是,如果您的表格中包含大量数据(请参阅数百列),并且只有某些数据会在特定时间更新。如果您有数百万条记录得到更新,但只有某些列一起更新,而其他列保持相当静态,则可以将该表分成两个具有一对一关系的表,以防止数据库性能在整个过程中停滞不前更新过程。

+0

谢谢!这是非常有用的信息。我会在明天进一步研究它,并将在我的应用程序中实施它。 – user1992

1

如果通过“连接它们的外部表格”表示第三个表格,则表示不需要。

虽然您的关系表可以使用一些工作。你不希望有两个字段与用户ID。那会让你后来头疼。我建议设置这些表像这样:

USER 

user_id (pk) 
username 
password  --Potential security problems, but for academic purposes, sure. 
date_registered 
family_unit_id 


RELATIONSHIP 

family_unit_id (fk) 
user_id (fk) 
spouse_type --(e.g. husband, wife, etc.) 

现在你可以让你的多对多的关系做这个:

SELECT r.family_unit_id, r.user_id, u.username 
FROM RELATION r LEFT JOIN USER u ON r.user_id = u.user_id 

你一对一的关系将是东西是独一无二的到表格之间的相同记录。在你描述的情况下,与user_id(妻子)相关的user_id(丈夫)不是一对一的关系。通过您提供的内容,您可以通过连接数据的子集来建立一对一的关系,例如本例。

SELECT r1.family_unit_id, r1.username as HusbandName, r2.username as WifeName 
FROM (SELECT * FROM RELATION WHERE spouse_type = 'Husband') r1 
LEFT JOIN (SELECT * FROM RELATION WHERE spouse_type = 'Wife') r2 
    ON r2.family_unit_id = r1.family_unit_id 

上面的查询基本上得到两个表family_unit_ids独特的主键,并用丈夫或妻子相关联的用户ID。然后,你们一起加入他们。因为我们假设在这个例子中,在已婚家庭单位中永远不会有两个以上的配偶,这将是一对一的关系。

如果你想获得一个一对多的关系,您可以选择一切从用户表,然后在关系表连接,以显示谁是合作伙伴的关系:

SELECT u.username, r.user_id 
FROM USER u LEFT JOIN RELATIONSHIP r ON r.family_unit_id = u.family_unit_id 

当然,这会是一个微不足道的结果,因为你会有记录说约翰与约翰和玛丽有关系。但它说明了这一点。通常情况下,通过在此混合中添加更多表格,您将获得更多有用的一对多关系结果。

+0

感谢您的评论。我有点困惑。我想知道除了列的命名(user_one_id,user_two_id和user_id,family_unit_id)之外,我的表(关系)和你的区别是什么。 – user1992

+0

将user_one_id和user_two_id合并到一个字段中:user_id。或者,您可以指定家庭位置:husband_user_id,wife_user_id。指定一个/两个的问题是,任何一个人都可以符合标准,所以稍后搜索和加入会更困难。 – SandPiper

+0

当你遇到非传统家庭时,丈夫/妻子领域硬编码的缺点是。丈夫/丈夫,妻子/妻子等等。所以,这取决于你的数据库目标是什么以及你想接受什么样的数据。 – SandPiper

相关问题