关于基本设计的建议,首次数据库设计

Vah*_*ahx 9 mysql foreign-key database-design

我正在学习成为 Java 开发人员的课程。

该课程涉及使用数据库,但不幸的是,我们从未真正设计过任何数据库。

大多数情况下,我们会获得预制的数据库,并且必须在其上实现代码以插入、更新、读取或删除数据。

但是当我的最终测试到来时,我很可能会制作涉及数据库的东西,因此我想尝试设计一些较小的东西来掌握设计的窍门,因为我注意到一个好的数据库设计在以下情况下会产生很大的不同编写代码以使用它。

我希望这些类型的问题在这里是允许的,而且不会太宽泛。


这是我为一些简单的东西而制作的小设计clubsmembers带有addressesphonenumbers

  • 会有多个俱乐部。
  • 每个俱乐部都会有多个成员(显而易见)
  • 一个会员不能是多个俱乐部的成员
  • 一个成员可以有多个电话号码和电子邮件地址
  • 一个会员只能有一个地址
  • 一个地址可以属于不同的成员(夫妻或兄弟姐妹)

我最大的困惑:

  • 如果我想在Club描述所有者的列中添加一个列,谁也将成为成员,在不将同一成员列出两次的情况下,最好的方法是什么?

  • 我应该将所有表放在 id 的自动增量上还是这是一个坏主意?(优点/缺点?)

  • 如果我在外键选项卡中添加外键,这些外键会自动对应于正确的表还是我也必须将这些添加到列中?(见图2)

  • 和我可能是noobiest 的问题...我把外键phonenumberemail在他们各自的表中链接到一个person_Id 还是我应该把phoneNumber 和email Id 放在person 表中?

(我很抱歉图片中的语言不是英语,我希望这不是什么大问题)

设计

外键

MDC*_*CCL 13

对您个人问题的回答

如果我想在Club描述所有者的列中添加一个列,谁也将成为成员,在不将同一成员列出两次的情况下,最好的方法是什么?

If —as stated in your specifications— a Person can be a Member of only one Club, and you are interested in storing this datum simply as true or false, one option is adding a BIT(1) or a BOOLEAN (TINYINT) column to the Person table, and you may wish to call this column IsClubOwner. In this way, you can register the fact that a determined person is a club owner exclusively one time. Apart from that, this method also allows the possibility of retaining several people as owners of the same club occurrence. You can see a logical level depiction of this approach in Figure 1.

然而,您正在寻找最好的方法,根据我的经验,这种方法需要开发一个更具扩展性和多功能性的结构。在这方面,请在以下标题为“涵盖您的剩余规格”、“个人作为多个俱乐部的成员”和“成员和所有者作为单独的实体类型”部分中针对这些和其他要点进行建模练习的进展。

我应该把我所有的表都放在自动增量上id还是这是一个坏主意?(优点/缺点?)

如果你面对一个明确的指示表的定义具有这样的特性的列要求,并且该列有一个有效的上下文意思或服务就像是一个特定的目的替代广泛的自然PRIMARY KEY(PK),那么,你应该那样做。

否则,如果您没有上述要求,我认为这是不必要的,因为您必须在数据库中存储和管理一个无意义的额外列和(也许?)还有一个额外的 INDEX。

像往常一样,您必须分析每个案例及其整体影响,以决定如何继续。

如果我在外键选项卡中添加外键,这些外键会自动对应于正确的表还是我也必须将这些添加到列中?

在这方面,我对您的建议是手动创建您的数据库结构,编写您自己的DDL语句,直到您牢牢掌握该主题。如果这样做,您将更容易理解图形工具在“幕后”执行的过程。

例如,对我来说,创建如下语句:

CONSTRAINT FK_PersonPhoneNumber_to_Person FOREIGN KEY (PersonId)
REFERENCES Person (PersonId)
Run Code Online (Sandbox Code Playgroud)

比使用 GUI 工具执行此类任务更有指导意义,尤其是现在您正在构建您的第一个设计。

而我可能是最noobiest所有的问题...我是否把的外键phone_numberemail在各自的表链接到一个person_id或我应该把phone_numberemail ids在人的表?

就我个人而言,我认为这个问题和你所有的其他问题都是完全有效的并且上下文关系很好

回到我们关心的技术方面,这个精确的询问提供了一个很好的机会来回顾以下两个断言:

  • A Person can be reached through zero-one-or-many PhoneNumbers
  • A PhoneNumber can be used to reach one-to-many People

所以,我们可以得出这样的结论之间的许多一对多的关系PersonPhoneNumber,因此,我建议在创建关联表命名PersonPhoneNumber,以表示你的数据库,所述的关系。此表的 PK 应由两个不同的列组成:(PersonId指向 的外键 [FK] Person.PersonId)和PhoneNumber(引用 的 FK PhoneNumber.Number)。有关上述所有内容的逻辑级别描述,请参见图 1

另一方面,让我们检查以下两个命题:

  • A Person can be contacted via zero-one-or-many EmailAddresses
  • An EmailAddress can be used to contact exactly one Person

然后,是的,您应该PersonEmailAddress表中设置 FK 引用,并且该表也应该有一个复合 PK,它由列PersonIdAddress. 通过这种方式,可以保证相同的组合EmailAddress.PersonId,并EmailAddress.Address可以一次插入。

如果您还希望确保给定的EmailAddres.Address可以存储在一个单独的行中,您只需为此列建立一个UNIQUE CONSTRAINT

建议的逻辑数据模型

为了更清楚地展示我的建议,我包含了四个不同的IDEF1X [1]逻辑模型,如图 1图 2图 3图 4 所示。我将在相应部分中对每个功能中显示的最相关功能进行说明。您也可以从 Dropbox 下载一个 PDF,该 PDF 将讨论中的大多数元素集成在一个模型中。

涵盖您的剩余规格

关联人员和地址

让我们检查以下两个(稍微改写)与人员地址相关的断言:

  • A Person can only have one Address
  • An Address can belong to different People (couples or siblings)

因此,为了处理这些限制,您可以选择实施类似于您在图 1 中看到的数据模型。

图 1. 俱乐部和会员数据模型 - 第一规范

考虑到引用的模型,您应该遵循以下步骤:

  1. 创建一个表,称为PersonAddress修复Person和之间的关系Address。设置列PersonIdAddressId作为该表的化合物PK。

  2. 为该PersonAddress.PersonId列配置 UNIQUE CONSTRAINT以确保特定值最多可以插入到所述表的一行中。在逻辑层面上,这种情况意味着PersonAddress.PersonId已成为 ALTERNATE KEY [2]

  3. 如果AddressId确定的PersonAddress插入尝试中的值尚未存储,则让插入继续,否则,当该值已存在于一行中时,您必须检查 (a)PersonId已注册的人AddressId也已注册为Marriage.WifeId如果PersonId是男性(经由衍生基准Person.GenreCode(b)该PersonIdMarriage.HusbandIdPersonId是母(由于衍生Person.GenreCode,以及)。如果在适当的情况下满足这些条件之一,那么您应该让 INSERT 继续。

  4. 如果不满足上述条件,仍然有机会PersonAddress尝试插入成功。您必须检查PersonId所述插入 try 中涉及的值是否Progeny.ParentIdPersonId已注册PersonAddress.AddressId. 如果满足此条件,则意味着它们像在数据库中一样存储Siblings,因此此 INSERT 必须成功。

正如在任何关系数据库实现中一样,您应该认真考虑DMLACID 事务中执行您的操作,以便您可以保护您正在使用的数据的完整性一致性

参加您在评论中添加的要求:地址和电话号码同等服务于俱乐部和人员

在你想给的机会条件的地址电话号码,同时服务于人民俱乐部,你可能会使用的超型亚型的关系这是一个答案,如果您有兴趣,我会对这种结构进行更详细的处理。

在当前场景中,您可以定义一个名为 的新实体Person并将其Club作为子类型,这是Party一个法律界常用的术语,代表 (a) 一个人或 (b) 一群人(如第6 条所述)。使用此方法,Addresses(或PhoneNumbers)和People和之间的关系Clubs将通过Party超类型定义。有关此建议的描述,请参见图 2

图 2. 俱乐部和会员数据模型 - 第二个规范

聚会和地址

所以我们可以在这个新模型中读到:

  • A Party keeps zero-one-or-many Addresses
  • An Address is kept by one-to-many Parties

因此,存在涉及实体的多对多关系PartyAddressPartyAddress实体的方式表达。

派对和电话号码

此外,我们可以解释为:

  • A Party is reached through zero-one-or-many PhoneNumbers
  • A PhoneNumber is used by one-to-many Parties

这就是为什么我添加了PartyPhoneNumber描述在PartyPhoneNumber实体类型之间生效的多对多关联的实体。

派对和俱乐部或个人

那么,也可以这样读:

  • A Party is either a Club or a Person

因此,Party提供了一个连接任一 Clubs PeopleAddresses(或PhoneNumbers)。

作为多个俱乐部会员的人

正如@aldwinaldwin在他的回答中提到的,如果您想为一个提供成为多个俱乐部成员的功能,那么您可以包含一个名为的表,这将作为另一个多对多关系,这一次,自然,互连和。ClubMemberPersonClub

我要添加到上面这个表也可以在存储任何具体的目标有用的作为业主多的俱乐部,通过包括已经提到的手段IsClubOwner布尔列。事实上,可以说这个新表本身就是一个完整实体类型的表示。

如在展示图3,如表需要的列的由复合PKClubIdMemberId(一个角色名称[3]提供给PersonId),以及这些列必须也被定义为指向FKS,相应地,对ClubPerson

图 3. 俱乐部和会员数据模型 - 个人作为多个俱乐部的会员

适应性更强的结构

使用此设置,您还可以遵守声明 的初始规则a Person can be a member of only one Club,但您只需要向列中添加一个 UNIQUE CONSTRAINT MemberId,以便在不超过一次的情况下输入某个值。因此,正如您所注意到的,这种结构比图 1 中所示的结构更具适应性,因为通过删除 UNIQUE CONSTRAINT(或 INDEX),您将打开上述允许一个成为不同俱乐部成员的功能同时。

成员和所有者作为单独的实体类型

如你所知,关于角色的存储几个事实通过进行作为业主一的俱乐部-还有在其单纯的所有脑干真或假的属性-可以是非常有利的。例如,你可能想保留生效日期,其中一个明确的成为了 主人一的俱乐部,因此你可以通过引入称为一个独立的实体型管理这种情况ClubOwner,在所呈现如图4

图 4. 俱乐部和会员数据模型 - 会员和所有者作为单独的实体类型

一旦您基于这种新的实体类型构建了一个表,您就可以添加表示仅在 aPersonOwnera时起作用的特征的拟合列Club。如图所示,该表将保存一个由 FK 列组成的 PK,这些列引用Person.PersonIdClub.ClubId,这样ClubOwner.OwnerId(或ClubOwner.PersonId,如果您愿意)的任何组合ClubOwner.ClubId都可以插入,并且可以插入一次。

当然,使用此配置,如果 aPersonOwner特定对象的Club,则您仍然可以借助返回标量值的查询以布尔形式导出,该标量值可以评估为true 或 false


笔记

1. 信息建模的集成定义 ( IDEF1X ) 是一种非常值得推荐的数据建模技术,于1993 年 12 月被美国国家标准与技术研究院 ( NIST )定义为标准。它坚实基础的(一)一些理论文章的撰写由始发的的关系模型,即EF科德博士; 关于 (b)实体关系理论,由PP Chen 博士开发;以及 (c)逻辑数据库设计技术,由Robert G. Brown创建。值得注意的是,IDEF1X 是通过一阶逻辑形式化

2. ALTERNATE KEY是一个属性(或属性的组合),它包含唯一标识实体出现但未被选为相关实体类型的 PK 的值;每个实体类型可以有零个、一个或多个替代键。在 IDEF1X 模型中,它们被表示为“AK”加上其各自的编号,例如 AK1、AK2 等。它们通常通过UNIQUE CONSTRAINT(或UNIQUE INDEX)在SQL DDL结构中实现。

3.角色名称是指派给 FK 属性的符号(或别名),以表达它们在各自实体范围内的含义。自 1970 年以来,Codd 博士在题为“大型共享数据库的数据关系模型”的开创性论文中推荐使用它们。就其本身而言,IDEF1X——在关系实践方面保持保真——也提倡角色命名。