5

我希望你能在这里帮助我——我有一个关于设计 SQL 表的问题。我知道如何使用 C# 写入数据库并执行查询,但我从来没有真正需要设计一个。所以我想我会试一试只是我们感兴趣的。

假设我有一个名为family_surname 的表。在该表中,可能有 x 个family_members,例如从 2 人到 22 人不等。我如何根据family_surname引用family_members?

所以我会有姓氏史密斯、琼斯、布朗、泰勒等。

然后史密斯可能有 5 个成员,我想记录年龄、身高、体重等等。琼斯可能有 8 名成员 - 它可能因家庭而异。

我真的不想为每个成员列出 8 次“姓氏”——理想情况下,姓氏行会引用(或以某种方式指向)另一个表中的相应行。这就是我遇到麻烦的地方!

我希望我说得通;就像我说的,我只是感兴趣,但我想知道如何用两张桌子做到这一点。

无论如何,谢谢你的帮助,我很感激。

编辑感谢所有评论的人 - 当然这里有一些有用的信息,我很感激。我正在阅读和研究一些 SQL 代码,到目前为止它还不错。再次感谢各位!

4

4 回答 4

3

您要问的是关于标准化的问题。该表如下所示:

Create table surname (
    SurnameID int,
    Surname varchar(255)
)

其他表将使用 I'd 引用姓氏。此外,您可能希望 surnameid 是唯一的、主键和自动递增。这些是更高级的主题。

也就是说,我不确定姓氏是否适合像这样拆分。规范化数据的一个原因是维护关系完整性。在这种情况下,这意味着当您将“Smith”更改为“Jones”时,所有 Smiths 都会同时更改。我认为这不是你的问题。

于 2012-05-14T23:04:35.907 回答
2

是的,之前关于学习数据库规范化的答案可能是准确的,但对于初学者来说......

分解这个人的名字(名字和姓氏)可能有点多。除非您假设每个名为“琼斯”的人都是相关的。将每个表视为一个实体/对象,并尝试将它们尽可能地连接到现实世界的“对象”。由于一个人需要名字和姓氏(最小)来唯一标识他们,因此不应以这种方式对其进行规范化。

在您绘制的场景中,您应该有一个包含 PersonId、FirstName、LastName 的 Persons 表。如果需要,一个单独的表来存储其他信息。然而,由于这个人只能是一个身高、体重、年龄等......这些应该存储在 Persons 表中。

因此,您实际上只需要一张桌子。除非你开始输入电话号码、地址等。

于 2012-05-14T23:19:46.710 回答
0

分解可以如下进行

  1. 创建表姓氏(INT ID,姓氏 VARCHAR2(200))
  2. 创建表详细信息(INT ID,外键(SURNAME_ID)参考姓氏(ID),PARAM1,PARAM2 .....)

分解的粗略草图是

获取属性列表(SURNAME、PARAM1、PARAM2、....)。根据属性列表,可以推断出以下键: 1. (SURNAME) 2.(PARAM1,PARAM2...) 为每组键创建一个单独的表

于 2012-05-14T23:21:42.313 回答
0

我真的不想为每个成员列出 8 次“姓氏”

为什么?您是否测量了真实的数据量并确定它实际上是一个问题?

除非您计划拥有特定于姓氏的其他数据(并且独立于拥有该姓氏的人),否则姓氏不在自己的表中并没有错。你没有打破任何正常的形式。

事实上,您提出的建议可能是一个非常糟糕的主意,原因如下:

  • 首先,你需要一个 JOIN 来找出人的姓氏——这对性能不利。
  • 它使人员的插入/修改/删除变得复杂(并减慢了速度)。
    • 插入新人时,您必须搜索 surname 表以决定是否可以“重用”现有人或插入新人。
    • 修改(例如,当妻子采用丈夫的姓氏时)是删除(见下文)和插入的组合。
    • 一个姓氏可以在没有任何人的情况下存在吗?如果不是,则没有良好的声明完整性来强制执行此操作。充其量你需要编写一些触发器。
  • 毕竟,您最终可能不会节省太多空间 - 额外的表将有自己的存储开销(例如主键“下方”的索引),这可能会“吃掉”大部分预期的存储节省。
于 2012-05-15T19:06:43.510 回答