48

我有一个数据库,它将存储有关个人的个人资料。这些人有大约 50 个可能的领域。

有些是常见的东西,比如名字、姓氏、电子邮件、电话号码。

其他是爱好,技能,兴趣之类的东西

有些是身高,体重,肤色。

系统在不同时间使用这些组中的每一个。就能够通过数据库进行协商而言,我希望有 7 个表,每个表大约 8 个字段。最佳做法是什么?

编辑:数据将用于搜索引擎,用于查找配置文件匹配项。这会影响我在做什么吗?

4

9 回答 9

39

我在 Normalize 阵营。

以下是一些帮助您入门的提示:

从为每个“人”分配一些任意唯一标识符的过程开始。称它为PersonId或类似的东西。该标识符称为代理键。代理键的唯一目的是保证它与现实世界中的真人之间的一对一关系。在将某些其他属性的值与数据库中的“人”相关联时使用代理键。

在开发数据库布局时,您可能会发现代理键对于某些其他属性也是必要的(或至少有用的)。

查看您要管理的每个属性。问以下问题:任何给定的人是否对该属性只有一个值?

例如,每个人只有一个“出生日期”。但是他们怎么可能有“爱好”呢?可能是零到很多。单值属性(例如,出生日期、身高、体重等)是作为键进入公共表的候选者PersonId。此时不应关注每个表中的属性数量。

多值属性(例如爱好)需要稍微不同的处理。您可能希望为每个多值属性创建单独的表。以爱好为例,您可以创建下表PersonHobby(PersonId, Hobby)。此表中的一行可能类似于:(123, "Stamp Collecting")。通过这种方式,您可以根据需要为每个人记录尽可能多的爱好,每行一个。对“兴趣”、“技能”等做同样的事情。

如果有相当多的多值属性的组合PersonId + Hobby决定不了其他任何东西(即,你没有关于这个人做这个“爱好”或“兴趣”或“技能”的任何有趣的记录)你可能会一概而论将它们放入具有类似结构的属性值表中PersonAV(PersonId, AttributeName, Value)。这里的一行可能看起来像:(123, "Hobby", "Stamp Collecting").

AttributeName如果您走这条路,最好将表中的替换PersonAV为代理键并创建另一个表以将此键与其描述相关联。类似的东西:Attribute(AttributeId, AttributeName)。此表中的一行看起来像 (1, "Hobby"),对应的PersonAV行可能是(123, 1, "Stamp Collecting"). 通常这样做是为了如果您需要知道哪些AttributeNames在您的数据库/应用程序中有效,您可以在一个地方查找它们。想想你如何验证“兴趣”是否是一个有效值 AttributeName——如果你没有记录某个人有这个值,AttributeName那么你的数据库中就没有记录AttributeName——你怎么知道它是否应该存在?好吧,在Attribute表中查找!

某些属性可能有多个关系,这也会影响表的规范化方式。我在您的示例中没有看到任何这些依赖项,因此请考虑以下内容:假设我们有一个装满零件的仓库,PartId确定它WeightClassStockCountShipCost. 这建议一个类似的表:Part(PartId, WeightClass, StockCount, ShipCost). 但是,如果非关键属性之间存在关系,则应将它们排除在外。例如假设WeightClass直接确定ShipCost。这意味着WeightClass仅此一项就足以确定ShipCost并且ShipCost应该从Part表格中排除。

规范化是一门相当微妙的艺术。您需要确定数据模型中所有属性之间存在的功能依赖关系才能正确执行。仅仅提出功能依赖关系需要相当多的思考和考虑——但这对于获得正确的数据库设计至关重要。

我鼓励您在构建数据库之前花点时间更多地研究规范化。在这里度过几天将远远超过自己的回报。尝试在 Google/Wikipedia 上搜索“功能依赖”、“规范化”和“数据库设计”。阅读、学习、学习,然后正确构建它。

我就规范化数据库设计提出的建议只是对您可能需要采取的方向的提示。如果对您试图在应用程序中管理的所有数据没有深入了解,那么这里给出的任何建议都应该“持保留态度”。

于 2010-11-03T19:55:17.677 回答
38

这很难说,并且基于应用程序的要求。我会说研究一下数据库规范化,因为它将向您展示如何规范化数据库,并且它应该阐明您希望将哪些内容分离到他们自己的表等中。

于 2010-11-03T17:34:22.357 回答
9

我会推荐几张桌子。过度规范化很难管理,您最终会编写复杂的查询,最终导致性能下降。

仅在绝对需要时进行规范化并以逻辑方式思考。由于您在上面提供的信息有限,我会选择三个表:

表 1:个人详细信息 表 2:活动 表 3:其他

还有其他技术可以加快性能,例如集群等,您可以根据需要使用这些技术。

于 2010-11-03T19:12:58.693 回答
7

IMO,担心存储的数据质量比您需要的表数量更重要。

例如,您是否需要跟踪更改?如果约翰在 2007 年 1 月是 5 英尺 2 英寸,在 2010 年 10 月是 5 英尺 11 英寸,你想知道吗?如果是这样,您需要将人与身高分开,分成两张桌子。

爱好怎么样——他们只能有3个爱好吗?他们能有更多/更少吗?这是您将来要查询的内容吗?如果是这样,您需要一个单独的表。

你应该阅读数据库设计和规范化(这个站点本身有几个优秀的线程)。

https://stackoverflow.com/questions/tagged/normalization

于 2010-11-03T17:40:52.967 回答
6

根据您的描述,我当然会将其分解为多个表格。不过,我不会拆分任意数量的列,而是尝试考虑组成实体或匹配您将用于命中数据的访问模式的列的逻辑集合

于 2010-11-03T17:36:47.327 回答
5

除非每个人都有相同数量的爱好(即每个人都有列出 2 个爱好),否则应该标准化。

与人员始终为 1 对 1 的字段应位于同一个表中。以年龄为例。没有人会有两个不同的年龄。

于 2010-11-03T17:42:52.463 回答
4

没有 100% 正确的数据库组织,只有一个足以满足您的目的。如果您没有预见到将来会超越单个优秀数据库服务器的功能,那么规范化数据并使用大量约束,例如外键、级联删除等,这将使您的数据库成为一种愉快的工作。另一方面,如果您查看许多具有数十亿请求的应用程序的数据库,您会发现它们以性能和可伸缩性的名义放弃了很多这些细节。

于 2010-11-03T17:38:40.160 回答
3

这个问题没有正确答案,因为它在很大程度上取决于您将在何时以及如何使用数据、数据更改的频率以及数据库上的使用量。

我个人会做的是将您的数据组织成逻辑实体并基于这些实体创建表。这至少是我要开始的地方。

于 2010-11-03T17:35:22.207 回答
2

许多小表,即规范化在这里是最好的。它提供了灵活性,减少了冗余和更好的数据库组织。

于 2010-11-03T17:36:07.277 回答