对您个人问题的回答
如果我想在其中添加Club
描述所有者(也将是成员)的列,那么最好是在没有两次列出相同成员的情况下的最佳方法?
如果-如您的规范中所述- a Person can be a Member of only one Club
且您希望将该数据简单地存储为true或false,则一种选择是在表中添加a BIT(1)
或BOOLEAN
(TINYINT
)列Person
,您不妨调用此列IsClubOwner
。这样,您可以一次注册一个确定的人是俱乐部所有者的事实。除此之外,该方法还允许保留多个人作为同一家具乐部的所有者。您可以在图1中看到此方法的逻辑层次描述。
但是,您正在寻找最佳方法,根据我的经验,这种方法需要开发出更加可扩展和通用的结构。在这方面,请遵循以下针对这些和其他要点的建模练习的进展,在标题为“涵盖其余规格”,“多个俱乐部成员的人”和“成员和所有者为独立实体类型”的部分中。
我应该将所有表格都放在id
或的自动增量上吗?(好处/缺点?)
如果你面对一个明确的指示表的定义具有这样的特性的列要求,并且该列有一个有效的上下文意思或服务就像是一个特定的目的替代了广泛的自然PRIMARY KEY(PK),那么,您应该以这种方式进行。
否则,如果您没有上述要求,那么我认为这是不必要的,因为您必须在数据库中存储和管理无意义的额外列,以及(也许吗?)额外的INDEX。
像往常一样,您必须分析每种情况及其整体影响,以便决定如何进行。
如果在“外键”选项卡中添加外键,这些外键会自动对应于正确的表吗?还是也必须将它们添加到列中?
在这方面,我的建议是手动创建数据库结构,编写自己的DDL
语句,直到您牢牢掌握该主题。如果这样做,您将更容易理解图形工具正在“幕后”执行的过程。
例如,对我而言,创建如下语句:
CONSTRAINT FK_PersonPhoneNumber_to_Person FOREIGN KEY (PersonId)
REFERENCES Person (PersonId)
比使用GUI工具执行此类任务更具指导性,尤其是在您正在构建第一个设计时。
而我可能是最noobiest所有的问题...我是否把的外键phone_number
并email
在各自的表链接到一个person_id
或我应该把phone_number
和email
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
指向的FOREIGN KEY [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,该复合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
已经成为另一个关键字[2]。
如果该值AddressId
在确定PersonAddress
插入的尝试还没有被已经存储,然后让插入继续,否则,当这种价值在一排已经存在,你必须检查(一)PersonId
谁已经注册了AddressId
也注册为Marriage.WifeId
如果PersonId
是男性(通过导出的基准Person.GenreCode
)或(b),PersonId
则Marriage.HusbandId
当PersonId
是女性时(也是通过得出),则是Person.GenreCode
。如果在适当的情况下满足了这些条件之一,则应继续执行INSERT。
如果不满足上述条件,则仍有PersonAddress
插入尝试成功的机会。您必须检查PersonId
所述插入尝试中涉及的值是否Progeny.ParentId
与PersonId
已注册的共享至少一个值PersonAddress.AddressId
。如果满足这个条件,那么就意味着它们保存为Siblings
在数据库中,所以这个INSERT必须成功。
与在任何关系数据库实现中一样,您应该认真考虑DML
在ACID Transactions中执行操作,以便可以保护正在使用的数据的完整性和一致性。
满足您在评论中添加的要求:地址和电话号码同时适用于俱乐部和人员
如果您希望有机会提供地址和电话号码同时服务于个人和俱乐部,则可以利用超类型与子类型的关系。如果您有兴趣,这里提供了一个答案,在此我对这种结构进行了更详细的介绍。
在当前情况下,您可以定义一个名为的新实体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,如表需要的列的由复合PK ClubId
和MemberId
(一个角色名称[3]提供给PersonId
),以及这些列必须也被定义为指向FKS,相应地,对Club
和Person
。
更具适应性的结构
使用此设置,您还可以遵守最初的规则,该规则指出a Person can be a member of only one Club
,但您只需要向该MemberId
列添加UNIQUE CONSTRAINT ,这样就可以在不超过一种情况下输入某个值。所以,你可以注意到,这种结构更有适应性,在所示的图1通过删除唯一约束(或指数),因为你会打开允许一个的上述功能的人成为会员不同的俱乐部在同时。
成员和所有者分别为实体类型
如你所知,关于角色的存储几个事实通过进行人作为业主一的俱乐部 -还有在其单纯的所有脑干真或假的属性-可以是非常有利的。例如,你可能想保留生效日期,其中一个明确的人成为了 主人一的俱乐部,因此你可以通过引入称为一个独立的实体型管理这种情况ClubOwner
,在所呈现如图4。
一旦基于这种新的实体类型构造了一个表,就可以添加表示当a Person
为Owner
a 时独有的特征的拟合列Club
。如图所示,该表将包含一个由FK列组成的PK,该列引用Person.PersonId
和Club.ClubId
,这样,ClubOwner.OwnerId
(或ClubOwner.PersonId
,如果愿意)的任何组合ClubOwner.ClubId
都可以插入到一个机会中。
当然,如果返回的标量值可以评估为true或false,则使用这种配置,如果a Person
是Owner
特定的Club
,您仍然可以以布尔形式导出。
笔记
1.信息建模集成定义(IDEF1X)是一种高度推荐的数据建模技术,该技术已于1993年12月由美国国家标准技术研究院(NIST)定义为标准。它坚实基础的(一)一些理论文章的撰写由始发的的关系模型,即EF科德博士 ; (b)由陈PP博士开发的实体关系理论;以及(c)Robert G. Brown创建的逻辑数据库设计技术。值得注意的是,IDEF1X形式化通过的方式一阶逻辑。
2. ALTERNATE KEY是一个属性(或属性的组合),具有唯一标识一个实体出现但未被选择为相关实体类型的PK的值;每种实体类型可以具有零个,一个或多个ALTERNATE KEYS。在IDEF1X模型中,将它们表示为“ AK”加上其各自的编号,例如AK1,AK2等。它们通常通过UNIQUE CONSTRAINT(或UNIQUE INDEX)以SQL DDL结构实现。
3. 角色名称是分配给FK属性的符号(或别名),目的是表达它们在各自实体范围内的含义。Codd博士自1970年以来就在其开创性论文“大型共享数据库的数据关系模型”中建议使用它们。就其本身而言,IDEF1X(保持忠实于关系实践)也提倡角色命名。
clubId
也要输入电话号码,并将club或person设置为null吗?