关系数据库设计(MySQL)

Posted

技术标签:

【中文标题】关系数据库设计(MySQL)【英文标题】:Relational Database Design (MySQL) 【发布时间】:2010-12-01 14:07:39 【问题描述】:

我正在为一个基于“人才”的网站启动一个新项目 - 例如:

型号 演员 歌手 舞者 音乐家

我建议这样做的方式是,每个人才都有自己的表,并包含一个 user_id 字段以将记录映射到特定用户。

在该网站上注册的任何用户都可以为这些人才中的一个或多个创建个人资料。人才可以有子人才,例如演员可以是电视演员、戏剧演员或配音演员。

例如,我有用户 A - 他是模特(走秀模特)和演员(电视演员、戏剧演员、配音演员)。

我的问题是:

    我是否需要创建单独的表来存储该用户的子人才?

    我应该如何为该用户执行***人才的查找? IE。在用户表中应该有每个人才ID的字段吗?或者我应该在每个***人才表中执行查找以查看其中是否存在该 user_id?

    还有什么我需要注意的吗?

【问题讨论】:

【参考方案1】:

在回答您的问题之前...我认为 user_id 不应该在 Talents 表中...这里的主要思想是“对于 1 个人才,您有很多用户,而对于一个用户,您有多个人才”..所以关系应该是 NxN,你需要一个中间表

见:many to many

现在

我是否需要创建单独的表来存储这些子人才 用户?

如果您想做一些动态的事情(添加或删除子人才),您可以使用递归关系。那是一张和自己相关的表

TABLE TALENT
-------------
id  PK
label
parent_id PK FK (a foreign key to table Talent)

见:recursive associations

我应该如何为此进行***人才的查找 用户? IE。在用户表中应该 每个ID都有字段 天赋?或者我应该执行查找 在每个***天赋表中看到 如果那个 user_id 存在在那里?

如果您以前使用过该模型,那么进行查询可能是一场噩梦,因为您的表 Talents 现在是一棵可以包含多个级别的树。您可能希望将自己限制在一定数量的级别上想要在你的人才表中,我想两个就足够了..这样你的查询会更容易

还有什么需要注意的吗?

使用递归关系时...外键应允许为空值,因为***人才不会有 parent_id...

祝你好运! :)

编辑:好的..我已经创建了模型..为了更好地解释它

编辑 第二个模型(圣诞树的形状 =D )请注意,模型与人才和演员与人才之间的关系是 1x1 关系,有不同的方法可以做到这一点(@ 987654323@)

查找用户是否有才能..在查询中加入三个表 =) 希望这会有所帮助

【讨论】:

嗨,我认为这可能被误解了,但基本上我想说的是会有单独的人才表,我在其中为每个具有该人才的用户创建条目。每个人才表中的字段将与该特定人才相关。 @pleasedontbelog +1 @GSTAR,其实我不认为它被误解了。我怀疑您看不到如何从上述设计中获得用户的所有才能?如果是这样,请告诉我们,我们可以演示如何获得用户拥有的所有才能,或所有具有才能的用户等... 您好,再次高兴ontbelong。如果我想存储特定于人才的信息该怎么办?例如,我需要存储特定于模型或特定于演员的信息。假设我创建了另外两个表(模型、演员) - 这些应该如何链接到用户? ...我认为它应该链接到 Talent_user 表,但我不知道如何。我也看不出在新表中插入 user_id 字段的意义... .. 所以你有不同类型的用户(演员和模特),根据用户的类型,你需要关联特定的人才,例如:演员只能与人才“唱歌”相关“跳舞”、“哭”,而模特只能与“摆姿势”、“微笑”、“呕吐”等才艺相关……或者你需要存储什么样的信息?……举个例子:) 【参考方案2】:

您应该有一张表,其中包含有关用户的所有信息(姓名、出生日期、有关用户的任何其他信息)。你应该有一张表,其中包含有关人才的所有信息(id、talentName、TopLevelTalentID(存储“子”人才,并引用“父”人才))。您应该为用户和人才之间的多对多关系创建第三个表:UserTalents,其中存储了 UserID 和 TalentID。

这里有一篇文章解释了如何到达 3rd NF:

http://www.deeptraining.com/litwin/dbdesign/FundamentalsOfRelationalDatabaseDesign.aspx

【讨论】:

【参考方案3】:

这是一个很好的问题,可以展示面向对象思维和关系建模之间的一些差异和相似之处。

首先,没有关于创建表的严格规则,这取决于您尝试建模的问题空间(但是,根本没有必要为每个表设置一个字段,并且构成设计错误 - 主要是因为它不灵活且难以查询)。 例如,在这种情况下完全可以接受的设计是有表格

Names (Name, Email, Bio)

Talents (TalentType references TalentTypes, Email references Names)

TalentTypes (TalentType, Description, Parent references TalentTypes)

上述设计将允许您拥有分层 TalentTypes 并跟踪哪些名称具有哪些才能,您将有一个可以从中获取所有名称的表(以避免注册重复),您有一个表来自您可以获得天赋列表,并且可以轻松添加新的天赋类型和/或子类型。

如果您确实需要在每种人才类型上存储一些特殊文件,您仍然可以将这些文件添加为引用一般人才表的表格。 举例说明

Models (Email references Talents, ModelingSalary) -- with a check constraint that talents contain a record with modelling talent type

请注意,这只是一个说明,在人才表中设置薪水而不是针对特定人才的表可能是明智的。

如果你最终得到了特定天赋的表格,你可以将天赋表格看作是一个特定天赋或子天赋继承属性的类。

【讨论】:

【参考方案4】:

抱歉,答案不正确。这是一种不同的方法。

在我看来,一个用户可以有多种职业(演员、模特、音乐家等)。通常我所做的就是首先考虑对象,然后将其转换为表格。在 P.O.O.你会有一个用户类和子类 Actor、Model 等。它们中的每一个也可以有 TvActor、VoiceOverActor 等子类......相同的主键(用户的 id),因此如果用户 4 是 Actor 和模型,那么您将在 Actor 的表上拥有一个注册表,在模型表上拥有另一个注册表,两者的 id=4

如您所见,存储很容易......复杂的部分是检索信息。那是因为数据库没有继承的概念(我认为 mysql 有但我没有尝试过).. 所以如果你现在想要用户 4 的子类,我看到三个选项:

为您拥有的每个天赋和子天赋表进行多个 SELECT,询问它们的 id 是否为 4。

SELECT * FROM Actor WHERE id=4;SELECT * FROM TvActor WHERE id=4;

做一个大查询,在左连接上连接所有人才和子人才表

SELECT * from User LEFT JOIN Actor ON User.id=Actor.id LEFT JOIN TvActor ON User.id=TvActor.id LEFT JOIN... WHERE User.id=4;

在与用户的 NxN 关系中创建一个人才表,以存储用户拥有的每个人才和子人才的参考,因此您不必询问所有表。您必须对 Talents 表进行查询,以找出您需要在第二个查询中询问哪些表。

这三个选项中的每一个都有其优点和缺点。也许还有另一个 =)

祝你好运

PS:啊,我找到了另一个选项 here 或者它可能只是改进的第二个选项

【讨论】:

干杯伙伴 - 我想我可能会选择第三个选项。显然存在一些数据复制(存储每个用户的人才列表),所以我必须确保在删除用户人才时,两个表中的条目都被删除。但除此之外,一切都很好! 嗨,伙计,最后一个简短的问题——我计划在我的 Talent_user 表中包含一个“活动”字段——这将确定用户是否打开/关闭了该人才。因此,当我进行查询以查找所有模型时,我想找到 active=1 的所有模型。我将如何为此创建联接? 我不认为你需要一个“活动”字段..这个想法是..如果一个用户是一个模型和一个 TvActor,那么在 Talent_User 表中,这个用户只会与人才“模特”和人才“TvActor”......这就是你知道用户有什么才能的方式。一旦你知道与用户相关的人才,问适当的表格 =) 我知道.. 它很复杂 不,我的意思是用户将能够手动关闭人才(而不是完全删除它)。该记录将保留在数据库中 - 它只会说它不活跃。我认为将这个开关放在 Talent_user 表中是有意义的。或者如果我们把开关放在实际的表中会不会减少头痛 - 例如模型或演员表。

以上是关于关系数据库设计(MySQL)的主要内容,如果未能解决你的问题,请参考以下文章

关系数据库设计(MySQL)

关系数据库设计(MySQL)

mariadb(mysql)基本介绍

MYSQL01_数据库的概述关系型和非关系型数据库区别设计规则

mysql数据库关系表设计原则

mysql之设计数据库