Vah*_*ahx 9 mysql foreign-key database-design
我正在学习成为 Java 开发人员的课程。
该课程涉及使用数据库,但不幸的是,我们从未真正设计过任何数据库。
大多数情况下,我们会获得预制的数据库,并且必须在其上实现代码以插入、更新、读取或删除数据。
但是当我的最终测试到来时,我很可能会制作涉及数据库的东西,因此我想尝试设计一些较小的东西来掌握设计的窍门,因为我注意到一个好的数据库设计在以下情况下会产生很大的不同编写代码以使用它。
我希望这些类型的问题在这里是允许的,而且不会太宽泛。
这是我为一些简单的东西而制作的小设计clubs
,members
带有addresses
和phonenumbers
。
- 会有多个俱乐部。
- 每个俱乐部都会有多个成员(显而易见)
- 一个会员不能是多个俱乐部的成员
- 一个成员可以有多个电话号码和电子邮件地址
- 一个会员只能有一个地址
- 一个地址可以属于不同的成员(夫妻或兄弟姐妹)
我最大的困惑:
如果我想在
Club
描述所有者的列中添加一个列,谁也将成为成员,在不将同一成员列出两次的情况下,最好的方法是什么?我应该将所有表放在 id 的自动增量上还是这是一个坏主意?(优点/缺点?)
如果我在外键选项卡中添加外键,这些外键会自动对应于正确的表还是我也必须将这些添加到列中?(见图2)
和我可能是noobiest 的问题...我把外键
phonenumber
和
(我很抱歉图片中的语言不是英语,我希望这不是什么大问题)
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_number
并person_id
或我应该把phone_number
和ids
在人的表?
就我个人而言,我认为这个问题和你所有的其他问题都是完全有效的,并且上下文关系很好。
回到我们关心的技术方面,这个精确的询问提供了一个很好的机会来回顾以下两个断言:
A Person can be reached through zero-one-or-many PhoneNumbers
A PhoneNumber can be used to reach one-to-many People
所以,我们可以得出这样的结论之间的许多一对多的关系Person
和PhoneNumber
,因此,我建议在创建关联表命名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
然后,是的,您应该Person
从EmailAddress
表中设置 FK 引用,并且该表也应该有一个复合 PK,它由列PersonId
和Address
. 通过这种方式,可以保证相同的组合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 中看到的数据模型。
考虑到引用的模型,您应该遵循以下步骤:
创建一个表,称为PersonAddress
修复Person
和之间的关系Address
。设置列PersonId
和AddressId
作为该表的化合物PK。
为该PersonAddress.PersonId
列配置 UNIQUE CONSTRAINT以确保特定值最多可以插入到所述表的一行中。在逻辑层面上,这种情况意味着PersonAddress.PersonId
已成为 ALTERNATE KEY [2]。
如果AddressId
确定的PersonAddress
插入尝试中的值尚未存储,则让插入继续,否则,当该值已存在于一行中时,您必须检查 (a)PersonId
已注册的人AddressId
也已注册为Marriage.WifeId
如果PersonId
是男性(经由衍生基准Person.GenreCode
)或(b)该PersonId
是Marriage.HusbandId
当PersonId
是母(由于衍生Person.GenreCode
,以及)。如果在适当的情况下满足这些条件之一,那么您应该让 INSERT 继续。
如果不满足上述条件,仍然有机会PersonAddress
尝试插入成功。您必须检查PersonId
所述插入 try 中涉及的值是否Progeny.ParentId
与PersonId
已注册PersonAddress.AddressId
. 如果满足此条件,则意味着它们像在数据库中一样存储Siblings
,因此此 INSERT 必须成功。
正如在任何关系数据库实现中一样,您应该认真考虑DML
在ACID 事务中执行您的操作,以便您可以保护您正在使用的数据的完整性和一致性。
在你想给的机会条件的地址和电话号码,同时服务于人民和俱乐部,你可能会使用的超型亚型的关系。这是一个答案,如果您有兴趣,我会对这种结构进行更详细的处理。
在当前场景中,您可以定义一个名为 的新实体Person
并将其Club
作为子类型,这是Party
一个法律界常用的术语,代表 (a) 一个人或 (b) 一群人(如第6 条所述)。使用此方法,Addresses
(或PhoneNumbers
)和People
和之间的关系Clubs
将通过Party
超类型定义。有关此建议的描述,请参见图 2。
聚会和地址
所以我们可以在这个新模型中读到:
A Party keeps zero-one-or-many Addresses
An Address is kept by one-to-many Parties
因此,存在涉及实体的多对多关系Party
并Address
以PartyAddress
实体的方式表达。
派对和电话号码
此外,我们可以解释为:
A Party is reached through zero-one-or-many PhoneNumbers
A PhoneNumber is used by one-to-many Parties
这就是为什么我添加了PartyPhoneNumber
描述在Party
和PhoneNumber
实体类型之间生效的多对多关联的实体。
派对和俱乐部或个人
那么,也可以这样读:
A Party is either a Club or a Person
因此,Party
提供了一个连接从任一 Clubs
或 People
到Addresses
(或PhoneNumbers
)。
正如@aldwinaldwin在他的回答中提到的,如果您想为一个人提供成为多个俱乐部成员的功能,那么您可以包含一个名为的表,这将作为另一个多对多关系,这一次,自然,互连和。ClubMember
Person
Club
我要添加到上面这个表也可以在存储任何具体的目标有用的人作为业主多的俱乐部,通过包括已经提到的手段IsClubOwner
布尔列。事实上,可以说这个新表本身就是一个完整实体类型的表示。
如在展示图3,如表需要的列的由复合PKClubId
和MemberId
(一个角色名称[3]提供给PersonId
),以及这些列必须也被定义为指向FKS,相应地,对Club
和Person
。
适应性更强的结构
使用此设置,您还可以遵守声明 的初始规则a Person can be a member of only one Club
,但您只需要向列中添加一个 UNIQUE CONSTRAINT MemberId
,以便在不超过一次的情况下输入某个值。因此,正如您所注意到的,这种结构比图 1 中所示的结构更具适应性,因为通过删除 UNIQUE CONSTRAINT(或 INDEX),您将打开上述允许一个人成为不同俱乐部成员的功能同时。
如你所知,关于角色的存储几个事实通过进行人作为业主一的俱乐部-还有在其单纯的所有脑干真或假的属性-可以是非常有利的。例如,你可能想保留生效日期,其中一个明确的人成为了 主人一的俱乐部,因此你可以通过引入称为一个独立的实体型管理这种情况ClubOwner
,在所呈现如图4。
一旦您基于这种新的实体类型构建了一个表,您就可以添加表示仅在 aPerson
是Owner
a时起作用的特征的拟合列Club
。如图所示,该表将保存一个由 FK 列组成的 PK,这些列引用Person.PersonId
和Club.ClubId
,这样ClubOwner.OwnerId
(或ClubOwner.PersonId
,如果您愿意)的任何组合ClubOwner.ClubId
都可以插入,并且可以插入一次。
当然,使用此配置,如果 aPerson
是Owner
特定对象的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——在关系实践方面保持保真——也提倡角色命名。
归档时间: |
|
查看次数: |
1824 次 |
最近记录: |