12

在尝试学习数据存储的艺术时,我一直在尝试获取尽可能多的可靠信息。PerformanceDBA 在以下帖子中发布了一些非常有用的教程/示例:我的数据是否标准化?关系表命名约定我已经在这里问了这个模型的一个子集问题。

因此,为了确保我理解他提出的概念并且我在其他地方看到过,我想更进一步,看看我是否掌握了这些概念。因此,这篇文章的目的,希望其他人也可以从中学习。我呈现的一切对我来说都是概念性的,用于学习而不是在某些生产系统中应用它。从 PerformanceDBA 获得一些输入也很酷,因为我使用他的模型开始,但我感谢任何人提供的所有输入。

由于我是数据库新手,尤其是建模新手,我将首先承认,由于缺乏该主题的专业知识,我可能并不总是提出正确的问题、清楚地解释我的想法或使用正确的措辞。所以请记住这一点,如果我偏离轨道,请随时引导我朝着正确的方向前进。

如果对此有足够的兴趣,我想从逻辑阶段到物理阶段来展示过程的演变,并在 Stack 上分享。不过,我将保留此线程用于逻辑图,并为其他步骤启动新线程。根据我的理解,我最终将构建一个 MySQL 数据库来运行一些测试,看看我想出的东西是否真的有效。

这是我想在这个概念模型中捕捉到的东西的列表。为 V1.2 编辑

  1. 这样做的目的是列出乐队、他们的成员和他们将出现的活动,以及提供音乐和其他商品待售
  2. 会员将能够与朋友配对
  3. 成员可以对乐队、他们的音乐和他们的活动进行评论。
    • 每个成员只能对给定项目进行一次评论,尽管他们可以编辑他们的评论并且历史记录将被保留。
    • 乐队成员将有机会就与他们关联的乐队的评论写一条评论。集体作为一个乐队,每条评论只允许发表一条评论。
    • 然后,成员可以对所有评论和评论进行评分,但每个给定实例只能评分一次
  4. 会员可以选择自己喜欢的乐队、音乐、商品和活动
  5. 乐队、歌曲和活动将被分类为它们所属的类型,然后在必要时进一步细分为子类型。一个乐队或活动可以分为一个以上的流派/子流派组合。
  6. 活动日期、时间和地点将发布给特定乐队,成员可以表明他们将参加活动。一个活动可以由多个乐队组成,多个活动可以在同一天在一个地点举行
  7. 每一方都将绑定到至少一个地址,并且应保留地址历史记录。每一方也可以一次绑定到多个地址(即账单、运输、物理地址)
  8. 将存储乐队、乐队成员和普通成员的个人资料。

就是这样,可能有点涉及,但希望随着过程的发展和社区提供的输入,对许多人来说可能是一个很好的学习工具。有输入吗?

替代文字

EDIT v1.1 响应 PerformanceDBA

U.3) 这意味着数据库中没有除乐队商品以外的商品。正确的 ? 这是我最初的想法,但你让我思考。也许该网站想要出售自己的商品,甚至是乐队的其他商品。不确定要为此制作什么模组。是否需要对目录部分进行全面修改,还是只需要与乐队存在的识别关系?尝试了一个模组来销售完整的专辑或歌曲。无论哪种方式,它们都是电子格式,仅供下载。这就是为什么我将专辑列为由歌曲而不是 2 个单独的实体组成的原因。

U.5)我理解你提出的关于与收藏的循环关系的内容。我想了解这个“它要么是一个具有某种形式的差异化(FavoriteType)的实体,它可以识别它的处理方式”,但我不清楚如何去做。我在这里想念什么?

u.6) “业务规则这可能是您唯一薄弱的领域。”<br> 感谢您的诚实回应。我将重新解决这些问题,但我希望首先通过我回复给您的回复来消除我脑海中的一些困惑。

Q.1)是的,我希望接受、拒绝和阻止。我不确定您指的是如何改变逻辑模型?

Q.2)一个人不必是用户。他们只能作为乐队成员存在。这就是你要问的吗?

小问题

零个、一个或多个……哎呀,我承认我在构建模型时忘记了这一点。我按原样提交此版本,并将在未来版本中解决。我需要阅读更多关于约束检查的内容,以确保我理解了一些事情。

M.4)取决于您是否设想未来的 OrderPurchase。你能扩展一下你的意思吗?

替代文字

EDIT V1.2 响应 PerformanceDBA 输入...

得到教训。

  1. 我混合了识别/非识别和基数(即流派/子流派)的概念,并且不一致地这样做会使事情变得更糟。
  2. 逻辑图中不需要关联表,因为可以在物理模型中描述并扩展它们的多对多关系。
  3. 我在很多关系中都忽略了基数
  4. 使用有效的动词短语阅读关系以确保我正在建模我想要完成的事情的重要性。

U.2) 在这个模型的概念中,只需要跟踪一个场地作为一个事件的位置。无需收集更多数据。话虽如此,活动将在给定的 EventDate 举行,并将在 Venue 举办。场地将在给定日期举办多个活动,并可能举办多个活动。在我的新模型中,我的想法是 EventDate 已经绑定到 Event 。因此,Venue 不需要与 EventDate 建立关系。您在 U.2 下列出的第 5 和第 6 个项目符号)让我质疑我的想法。我在这里错过了什么吗?

U.3)是时候将物品和乐队之间的链接移到物品和派对上了吗?就目前的设计而言,我认为不可能出售与您提出的乐队无关的商品。

U.5)我根据您的输入离开,而不是使其成为离散的超类型/子类型关系,因为我看不到这种类型的汇总有什么好处。

附加修订

AR.1)完成FavoriteItem 的练习后,我觉得Item to Review 需要一个多对多的关系,所以要指出。必要的? 在此处输入图像描述

好的,我们去 v1.3

我在这个版本上花了几天时间,来回研究我的设计。一旦逻辑过程完成,因为我想看看我是否走在正确的轨道上,我将深入了解我所学到的东西以及我作为初学者在这个过程中遇到的麻烦。这个版本的重点是它需要输入一些键来帮助查看我过去缺少的东西。经历做矩阵的过程也被证明是有很大帮助的。无论如何,如果不是 PerformanceDBA 提供的输入,我仍然会是一个迷失的灵魂,在黑暗中徘徊。谁知道我目前的设计可能会再次证明我仍然存在,但我学到了很多东西,所以我知道我至少手上有一个手电筒。

在这一点上,我承认我仍然对识别和非识别关系感到困惑。在我的模型中,我必须使用具有非空值的非标识关系来加入我想要建模的关系。在阅读大量有关该主题的内容时,似乎对该主题存在很多分歧和优柔寡断,因此我做了我认为代表模型中正确事物的事情。何时强制(识别)和何时自由(非识别)?有人有输入吗?

在此处输入图像描述

编辑 V1.4

好的,接受了 V1.3 输入并为这个 V1.4 清理了东西

目前正在开发 V1.5 以包含属性。

在此处输入图像描述

编辑 V1.6

好的,我已经有一段时间没有在这里发帖了,但这个项目的工作仍在进行中。我现在发布 V1.6,其中包括与上次发布 V1.4 相比的一些更改。这个版本展示了 Keys 的进一步发展。它仍然不包括属性或任何 AK 或 IE。我已经开始研究物理模型,并用它来帮助处理属性并尝试阐明我在定义 AK 和 IE 时遇到的问题。逻辑模型的下一篇文章将包括这些键和属性。

在此处输入图像描述

4

2 回答 2

9

致谢

我不得不说,您在 (a)掌握上一个问题中提供的建模元素和 (b)应用它们方面做得非常出色。你在一天之内走了很长一段路。这是一个美妙的事实,即,给予正确的教育,有能力的人有能力做伟大的事情,发挥自己的力量。

方法

鉴于您声明的目标和您展示的能力(更不用说,我在 SO 上处理的第一个寻求者,对于发布 ERD 而不是一堆 DDL 的 Db Design 问题),我不会提供答案。我会给你方向和指导,你必须改进自己的模型。

当然,我也会介绍具体内容,但我会完整介绍一两个学科领域,而不是全部。您可以选择它并将其应用于所有主题领域。

我没有回应核心主题领域,因为我们仍在处理识别实体。解决后Reviews,等会更容易;交易实体取决于识别实体。

方向

D.1) 我知道我说过我需要查看整个模型。有一个例外。历史或时间或审计数据(例如,编辑和存储的版本)。在这个早期阶段,它们可以被搁置;在逻辑模型完成之前实施。这是因为(a)它们是一些父级的简单依赖项(b)需要首先对所有其他表进行建模,以及(c)排除不必要的复杂性,从而使我们能够专注于相关的场地。

  • 特别是,您可以忽略动词短语中的时态(否则版本表的每个位置都需要Has/Had)。暂时保持现在时,因为重点是建模,而不是归档。

未解决

U.1) Optional Parent
完全不允许。不仅是 IDEF1X,而是任何完整性概念。如果定义了 FK 引用,则必须有父级。要允许可选的父级,必须删除(或不实施)FK 引用。根据定义,这样的条件将排除结果作为“关系数据库”的资格。例如。Address:Order.

  • 当然,在发达国家,出于法律或税收的原因,Order必须要有一个;Address这与标准要求问题是分开的。
    .

U.2) 事件
Party::PartyAddress正确;Address::PartyAdress是正确的。Event::Address需要工作。地址是一个识别参考表;如果使用,它将是父母,Event将是孩子。我把它留给你来识别/建模多个Events到一个位置,以及Events在一个或多个位置。

  • 可能涉及场地。或者一个EventOccurrence

  • 但是,如果它是Event发生在多个位置的泛型,则不需要实体,则Address它已经在Order.

U.3) 假设Catalog是传统意义上的条目(JCPenney 2011),即出售或出租的物品清单。

  • OrderSaleItem是正确的

  • 临界点。Catalog是 Dependent,并且只能Band作为 Asset 存在于 a 的上下文中。美好的。这意味着数据库中没有除 Band 商品以外的商品。正确的 ?

  • 我可以看到“与布鲁斯兄弟的晚间表演”是Event如何可以订购、开票和付款的。还审查,评论等。

  • 我看不出如何Song适应它。乐队是在销售专辑、歌曲还是两者兼而有之?

  • 有没有其他乐队商品:音乐会/活动纪念品;海报; 刻花眼镜?

  • 与您引用的命名约定以及数据库的其余部分一致,Catalog(内容)应命名为Item(行)。您已经(自然地?)在OrderSaleItem,( 而不是OrderSaleCatalog.

U.4) 类型

  • 没问题an Item is classified by one-to-many Genres

  • 我认为另外a Genre classifies one-to-many Items。关系是一对多的(当我们到达物理时,它将被解析为关联表)。

U.5) Favorite
的基数Item::Favorite被颠倒。当您更正该问题时,Favorite主题区域将需要进一步建模。

  • 同一对实体之间的循环关系或双重路径是未解决模型的信号。通常一个是正确的,另一个是多余的。(有例外,但不是在这里;当这种情况发生时,动词短语会区分它们。)

  • Band::Favoritexor中的任何一个Item::Favorite都是正确的,而不是两者都正确。

  • Item::Favorite似乎是正确的,因为Band已经在Item

  • 同样,Favorite乐队商品的一个实体听起来也不可靠。Favorite单个实体中的每个标识符都是一个Party. 当我们规范化时它会中断,还不如要求在这个阶段澄清标识符。它要么是一个具有某种区分形式的实体 ( FavoriteType) 来确定其处理方式;要么 或者一个Favorite用于乐队,另一个用于商品,在这种情况下不需要区分,消除了歧义。

U.6) 商业规则 这可能是你唯一薄弱的领域。一般反应。您已经分别完成了任务(所有建模与编写 BR)。这些与模型不匹配。当您经历下一个周期时,将业务规则作为指令,并同时调整它们,就像实体、关系和动词短语一样。

问题

Q.1) 用户/朋友
你完美地掌握了它的本质。以及关系的基数。(对此进行全面处理。)这对于 Accepted 是正确的Friend

  • 因此时态应该过去(与多数行一起使用)

  • Requested和pendingAccepted是少数。IsAccepted在位或布尔值中轻松实现。

  • 稍后您可能拥有IsRejectedIsBlocked(后者应该是一个单独的实体)。

  • 那是你需要的吗?

Q.2) a 的依据是Person is zero-to-many Users什么?

小问题

M.1) 仅单数。

M.2) Party Has zero-to-many Addresses。我认为他们必须有一个,以便进行业务交易(但也许不是全部Users)。

M.3) Order May Have zero-to-many Payments。“需要”意味着 firstPayment必须与Order.

  • 同样,对于任何强制子代(一对多而不是零对多),第一个子代必须与父代同时插入。这是通过企业数据库中的事务完成的,因为实现了即时约束检查不是延迟);小镇的小尽头为诸如延迟约束检查之类的愚蠢事情而争吵“更好”,然后花费他们的一半时间来弄清楚如何陷入他们创建的无限循环中,从而使他们陷入困境。MyNonSQL 根本没有,因此无需担心此实现。

M.4)OrderSaleItem应该是OrderItemxorOrder应该是OrderSale. 取决于你OrderPurchase对未来的设想。

▶学科领域示例◀

不熟悉关系数据库建模标准的读者可能会发现▶IDEF1X Notation◀很有用。

如前所述,我不提供完整的数据模型,仅提供指导。这只是一个选定主题领域的进展。它在任何方面都不“正确”或不完整。

  • 你的动词短语很棒。我提供了替代方案供您考虑,它们不是“正确”或“更好”。您需要选择他们或您自己的进度。目标是在每种情况下最简洁和准确的 VP。

  • Person没有正确和不正确的建议,User等待您的回答。但是我不得不在模型中使用一些东西;由于您已将它们建模为单独的,因此评估对位可能很有趣。

好的,所以继续改进模型,然后再次发布(只需编辑问题,留下标题段落,然后替换其余部分)。

V1.1 和响应

这当然是一个进步。

我以伪法律格式重新编号了项目,包括章节标题,以便我们可以在整个过程中保持编号,并不断添加。实际上,它也确实缓解了 SO 编辑问题。

U.3)是否需要对目录部分进行全面修改,或者只需要与乐队存在的识别关系?

  • 不。这是在这个级别工作的好处,你在这里做出的决定将是数据运行的铁路轨道,作为货运,或者不运行(因此需要替代运输和繁重的提升,在大量代码或附加数据仓库的形式)。而且这里的决定很便宜(建模时间,纸张)。

  • 现在一个项目只存在于乐队的上下文中。它是依赖的。要允许非乐队商品,它需要是独立的。然后现有的超级/子类型集群需要返工。

尝试了一个模组来销售完整的专辑或歌曲。无论哪种方式,它们都是电子格式,仅供下载。这就是为什么我将专辑列为由歌曲组成的原因

  • 行。但现在你只能卖专辑,不能卖歌曲。

而不是 2 个独立的实体。

  • 不确定你的意思(你两个独立的实体)。

  • 看来你还没有看到我的▶主题领域示例◀请注意,如果您现在打开它,它会包含我添加的位 V1.1;我没有改变昨天的 V1.0 响应。

  • 实际上,这意味着您应该在查看示例时再次查看我的 V1.0 答案。

U.5) ...但我不清楚如何做。我在这里想念什么?

  • 一个具有差异化的实体的示例是您拥有的任何超类型/子类型集群。Favorite 是超类型,BandFavourite 和 ItemFavourite 是子类型;允许每个分别引用 Band xor Item。

  • 您已经为 ItemFavourite 建模。现在的问题是,ItemFavourite 的事实是否意味着该乐队是最喜欢的?还是 BandFavourite 是一个离散的事实?在示例中,我对后者进行了建模,没有 Favourite::ItemFavourite/BandFavourite 结构。

Q.1)是的,我希望接受、拒绝和阻止。我不确定您指的是如何改变逻辑模型?

  • 对 V1.0 没有任何更改(我已经说过它非常完整),但您可能需要一个额外的实体。

  • Friend 中需要三个位或布尔指标。这将为这些状态提供服务:

    • Requested(但不接受)
    • Requested & Accepted
      .
  • 但是被阻止不是朋友(或者以前可能是朋友,但自从被阻止后就不是了)。因此,实体名称必须更改以反映(两个关系没有更改)x 或 Blocked 必须是一个单独的实体。第二个关系的两个不同含义导致复杂性,因此我会选择后者。

对于前者,我们有额外的状态:

  • Blocked
    .
    • 然后动词短语需要更改(为了清楚起见,我将包括 RoleName),其中一个具有替代含义。.
    • (在属性级别模型中会更清楚,这就是为什么我们用图片而不是文字来建模的原因;所以我已经包含了它。)

Q.2)一个人不必是用户。他们只能作为乐队成员存在。这就是你要问的吗?

  • 不,为什么我们需要区分 Person 和 User ?有哪些单独的操作或属性?到目前为止,我将 Person 和 User 视为同一个实体;Person 是没有活动的用户。

  • 这是最后一项,使我们无法处理核心主题领域。

M.3)我需要阅读更多关于约束检查的内容,以确保我理解了一些事情。

  • 现在不用担心;我给了你保持简单的理由(NonSQL 似乎简化了事情,但实际上它们使它变得更复杂)。MyNonSQL 没有这些功能,因此您可以消除对平台的考虑,只对 Cardinality 进行有意义的建模。

M.4)取决于您是否设想未来的 OrderPurchase。你能扩展一下你的意思吗?

  • 在模型的上下文中。您提供结构来制作 SalesOrders(项目)。因此,Item、Order 和 OrderItem。

  • 但是,如果您还提供了跟踪 PurchaseOrders 的结构(购买项目以及办公用品、租金等),那么您需要区分销售订单和采购订单。所以:

    • 物品
    • OrderSale 和 OrderSaleItem
    • OrderPurchase 和 OrderPurchaseItem

1.1版

U.2) 事件进展

  • EventDate 看起来不错。我会将关系定义为Event Was Perfromed On EvenDate

  • 虽然 ItemGenre 是完美的,但 Event::Venue 需要工作。这是您一贯犯的错误,因此需要做出解释。

    • 您已正确建模Venue,它是独立的,并且确实存在于Event. 但是Event May Be [Held] At zero-to-many [Independent] Venues是不可能的。

    • 活动在许多场地举行,场地举办许多活动。如果就是这样,既然这是逻辑层,你可以画一个多对多的关系,你就完成了。在物理级别,通过实现关联表来解决该关系,其中 PK 是两个父 PK,并且没有数据。(敌人就是一个很好的例子。)

    • 但是如果有数据(例如,您需要跟踪参加者的日期或人数等),那么它就不是关联表,而是另一个实体。发生在 Event 和 Venue 之间的事情。

    • EventDate 是一个不错的选择。我们已经有了它和日期。只需添加场地并搅拌。我将在事件和场地之间发生的事情称为表演。

  • 同样,EventAddress 已取得进展,但尚未完成。

    • 活动有地址还是场地有地址?(建模吧,不用多说)

    • 如果场地:您需要场地的所有历史地址(如派对),还是只需要当前地址(如订单)?

M.5) 子流派。你能解释一下为什么 SubGenre (a) 独立和 (b) Relation is Non-Identifying。

M.6) Item Is zero-to-many Favourites。因此:Item Is a Favourite of zero-to-many Users。同样,Each User Chooses zero-to-many Favourites. 因此Each User Chooses zero-to-many Favourite Items

V1.2 和响应

大进步。

U.2) 事件进一步推进

根据您的编辑以及新的要求,有些是,有些不是。数据模型的所有其他主题领域都非常完整(对于逻辑),这一领域很混乱,几乎没有解决。部分是因为增加了要求(没有抱怨,这发生在现实生活中;这是关于你如何处理它)。

我要在这里提出的主要观点是,数据模型应该始终对现实世界进行建模,而不仅仅是业务需求。(a) 将 DM 与变化的影响隔离开来,并且 (b) 为增加的需求提供了一个坚实的平台。这并不意味着您必须对整个现实世界进行建模,但您所建模的部分必须反映现实,而不是为了满足需求而被压扁。

其次,Event、Band-Event、Performance 等之间的区别并不清楚。现在,Event 是 Party-Band-Item-Event。这很好,但它不适用于按要求的新样式事件。

第三,您对 Address re Party 和 Order 有很好的处理,但不是 re Venue。

  • 由于您接受符合标准的模型并因此接受处理,因此地址是一个参考表。

    • 它是独立的(方角)

    • 实际上,您可以将地址及其上方的所有内容放在第一页上;将模型的这一部分制作为第二页,并且仅在此页面上具有地址。

    • 正确建模:一方有地址历史。他们必须至少有一个当前的 { IsBilling | 航运 | IsPhysical } 地址,基于正在执行的任何活动。

    • 正确建模:一个订单有一个 IsBilling Address(如果需要 IsShipping,则需要添加单独的 Relation)。

  • Address 不是 Venue 的子节点(也是独立的,正确的)。我不认为场地位于零对多地址中。(也许那是旧的 Cardinality-reversed 错误,但我不确定,因为 Event 和 Venue 的其他混淆。)

  • 实际上 Address::Order 是可疑的。(Q.3) 您是否希望订单引用任何有效地址或执行订单的一方的特定地址?

  • 返回事件。接受声明的 EventDate。很好,但是评论等适用于一般音乐会,而不是他们在蘑菇上表演的单一音乐会。选择 V1.3。

    • 您的术语 re 事件等与要求等一致,但它不支持所述要求。

    • 因此,让我们开始以在现实世界中使用“事件”的方式使用它,并以这种方式对其进行建模。我们一直称之为“Event”,Party-Band-Item,实际上是一个Performance。而且不是预定的通用,而是在特定地点的单个。

    • 这就是您对 EventDate 的意思,或者 EventDate 解析为 Performance。

如果你不介意,我就不打一千字,给你一张图。▶学科领域示例V1.2◀

  • 请注意,每个事件的多个波段已解决。

  • 动词短语直接来自天堂。一个地址托管了多个场地,每个场地都承办了多个活动,每个活动都是多个表演,每个表演都是一个派对-乐队-项目。

U.3)是时候将物品和乐队之间的链接移到物品和派对上了吗?就目前的设计而言,我认为不可能出售与您提出的乐队无关的商品。

  • 首先,我们需要使用关系术语,不是因为我是一个书呆子,而是因为真正的大师说它确实有助于过渡到关系世界。

  • 其次,我们无法通过“移动关系”来实现这一目标。

  • 您必须为非乐队商品建模:您将如何销售它;追踪它;得到报酬。是否需要评论和回复等。我看不出派对与它有什么关系,现在我们销售的是乐队物品,而不是派对物品。考虑参照完整性问题。

1.2版

AR.1)完成FavoriteItem 的练习后,我觉得Item to Review 需要一个多对多的关系,所以要指出。必要的?

  • 在 V1.1 中,一个 Item 有很多个 Review,一个 Review 就是一个 Item。一个人产生了许多评论(每个项目一个)。这是合乎逻辑的。

  • A Review is about many Items不合理。

  • 如果有的话,既然 FavouriteItem/FavouriteBand 已解决,Review 也需要同样的解决和区分:我们是否需要将 BandReview 与 ItemReview 区分开来?好的/坏的 ItemReview 表示好/坏的 BandReview 还是离散的?

    • 评论(就目前而言)不能与乐队或项目有关。这意味着两个外键,一个将 Null 和 Null FK 是不允许的。Item和Band已经分化了,分化成熟了。

    • 可以总结 ItemReviews 等,但这是另一回事。

U.7) 这给我们留下了一个需要解决的新问题。如果评论可以是关于乐队、专辑、歌曲或表演的,我们如何确保参考完整性。我们不需要 AlbumReview 来引用 SongReview 等。对其建模。

R.5) 该模型目前在项目级别提供流派,这意味着专辑和歌曲(可以通过 CHECK 约束禁止商品)。不是乐队。这可能就足够了,因为 (a) 乐队会随着时间而变化,(b) 项目级别的分类更精确,以及 (c) 乐队类型可以很容易地从他们的专辑或歌曲中得出。

  • 如果您需要单独的乐队流派,则需要添加它。

  • 事件类型呢?如果你需要它,我认为每个事件都会有一个流派。

  • 请记住,像 Venue 和 Genre 这样的表是主要数据库中的重要搜索条件。用于分析的向量。

    • 数据仓库男孩需要其作为维度添加到他们的事实中;在正确建模的数据库中,它们已经作为事实的维度存在。 向我展示所有安排了吸引超过 10,000 人的“民间音乐”活动的场地非常容易。
      .
  • 讨论点。不说上面是不正确的。我在数据库和 iTunes 中发现的是,精度很重要。当您可以拥有 Genre ::Specific Thing 时,为什么还要自由放任 Genre::Several things。如果您只有 Genre::Song,而 Song 只有一个 Genre,那么 Album 和 Band 就是精确的汇总。我们现在的样子,就看数据录入者的音乐知识了,而且 Genre::Thing 多,所以比较松。流派::歌曲很紧。

R.6)成员可以表明他们将参加未建模的活动。还要澄清兴趣与预订与出勤率。

R.8) 未建模。

M.3) 问题已结束,但动词短语保持不变。

M.7) 相对于关联表的逻辑模型。现在该问题已关闭,请删除逻辑模型的所有关联表;任何剩余的表(两个父级之间)都将包含数据。这意味着,遍历所有从属表并删除任何没有数据的表。因此 V1.3 应该不那么混乱。

M.8) 项目OrderItem。

M.9) 现在 Party-Person-User 已经解决了。Exclusive Subtype 结构需要一个Discriminator,并且 Constrainst 将用于强制完整性。有很多地方,PartyType 是要走的路。但是对于只有两个,一列IsBand还是IsPerson足够的。

M.10) 你已经纠正了基数反转的错误,但是一些动词短语仍然走错了路。

2011 年 1 月 27 日

实际上,我认为如果我们进入逻辑键/属性级别(而不仅仅是实体关系级别),很多这些问题会更清楚。现在是我们这样做的时候了。例如:

Q.3) 订单:地址可疑。该约束并不完全正确,因为这将允许订单具有任何地址,而不是特定于执行订单的一方的地址。

但是由于您是没有引用完整性的 MyNonSQL,您可能不知道它在实际 SQL 中是如何完成的,所以我将提供 FK 定义,它也恰好是 RI 约束。当您没有 SQL 时,期望您理解我的简洁语句是不公平的,这些语句基于 RM,规范化并由 SQL 支持。

  • 为了使这两个约束为真,由于每个约束中的 Party 必须相同(只有一个Order.PartyId),因此只允许属于 PartyId 的 PartyAddress 的子集。

▶地址限定示例◀

在第二部分继续...

于 2011-01-23T07:56:27.080 回答
3

... 第二部分

V1.3 和响应

圣托莱多!你在用煤气做饭,小伙子。所有的问题要么是次要的,要么与你正在学习的新步骤有关。

标识符与 Id 列

我不会在这里给你一个完整的纲要,因为我已经发布了至少 20 次关于Id列如何削弱数据库并剥夺它的关系能力。我将仅在这个问题的背景下处理这个问题。

  • 这里是▶一个例子◀,先详细检查问题。请注意,马克非常有能力,但完全卡住了。 然后阅读我的答案,然后查看数据模型。(请现在就这样做,它提供了上下文)

  • 我们的想法是数据建模为我们正在做的数据,你最终会得到一个数据库,xor在所有移动的东西上粘贴Id列,这阻碍了建模练习和规范化,你最终会得到一堆电子表格彼此“链接”,大量重复且没有性能。

  • 因此,[Table]Id从所有表中删除表单的所有列(不理会迁移的键,它们是正确的),除了以下表(这些是主要标识符,反映在整个数据库中。注意 ERwin 将如何更正所有子、孙等. 表:
    Party
    Address
    Item

关系/IDEF1X 标识符

您正在学习标识符。这些是自然键。用户使用的密钥,或已作为外键从父级迁移到子级的密钥。因此,这些不仅是识别关系,也是识别孩子。你的姓不仅告诉我关于你的事,也告诉我关于你父亲的事,也告诉我你是你父亲的儿子。想让它独一无二吗?没问题,只需添加一个名字。

您一直在阅读我的答案,查看我的数据模型,然后标识符添加到您的模型中。这比那要容易得多。ERwin(因为它实现了 IDEF1X)为您做到了。

  • 以派对、乐队和个人为例。Party 的标识符是PartyId
    (好吧,那是代理键,不是自然键;但是自然键Lastname, FirstName,BirthDate等很长,如果我们用它作为主键,它会被迁移到孩子,孙子,伟大-grandchildren,这是不可取的,所以我们添加一个短代理键,并将其设为主键)

  • 当您在ERwin中创建子类型,并指明Relation时,它会自动放置PartyId在Band和Person中,作为PK;它会将其标记为“(FK)”。(注意:我在模型中使用粗体表示(FK)。)

  • 就是这样,你完成了。Party::Band 为 1:0-1,Band Primary Key 为PartyId. 因为它是一个子类型,ERwin 将确保 Relation is Identification,因此父 PK 最终出现在子 PK 中,而 Dependent 子具有圆角。

    • 如果涉及子类型,那将是相同的,除了 Relation 可能不是 1::0-1,它可能是 1::1-n。在这种情况下,您需要添加另一个元素以使其唯一,例如 f FirstName,或SequenceNo
    • 你必须向 ERwin 表明你想要一个识别关系。(如果你不这样做,那么它是一个普通的 FK,列将位于该行的下方;表格将是独立的;角是正方形的)。
    • 如果在某个时候您决定使用这些 FK 列来形成 PK,您只需单击Relation并将其从 Non-identifying 更改为 Identification;列将移到线上方;角落将是圆的。

角色

  • 现在进行下一步。我们知道 Band::Party 是 1::1;该乐队是党的孩子;这Band.PartyId是完美的PK(不需要Id列)。对人也一样。但它们是愚蠢的名字,或者换句话说,Band 实际上是与 Person 不同的角色,它们都是 Party。所以我们要清楚地识别角色。

    • 在 Band 中,我们想调用PartyId,BandId来反映它的角色。编辑子类型符号和子类型之间的关系,而不是表。在对话框中,将 RoleName 填写为BandId。就是这样。你完成了。

    • 因此,以下从 ... 更改为:

      FloorItem.ItemId       FloorItemId
      BandItem.ItemId        BandItemId
      最后 ...
      Other.BandItemId       OtherId
      Album.BandItemId       AlbumId
      Song.BandItemId        SongId
      Performance.BandItemId PerformanceId

  • 删除所有[Table]Id列将留下没有 PK 的下表。现在,添加一Name列作为 PK。稍后您可以告诉我用户想要什么自然键,这些表的标识符:事件
    类型

  • PartyAddress 是我上面讨论的所有内容的一个示例(即正确建模)。它没有PartyAddressIdPartyIdAddressId共同组成PK。两种关系都在识别。

识别与非识别关系

在阅读大量有关该主题的内容时,似乎对该主题存在很多分歧和优柔寡断

  • 是的。不幸的是,如今任何拥有键盘和调制解调器的人都可以“发布”。人们将意见作为事实发表;他们发表关于他们一无所知的主题的废话。这让正在努力学习的人感到困惑。

  • 它是科学,不是魔法或黑魔法,不是意见。

  • 学习时,只阅读定义,只听那些清楚地转移科学的人(不要听那些对科学感到困惑或将科学视为艺术或受制于意见的人)。我们正在学习事实、物理定律,而不是对定律的看法;法律对全世界的每个人都同样适用。你不能向那些认为事实就是观点的人学习。

  • 让我们从顶部开始:

    1. 关系是定义标准(使孩子独立/依赖),而不是相反。

    2. 关系始终是父 PK 的子中的 FK 。

    3. 识别关系中,该 FK 是 PK(或 PK 的第一部分,其中 PK 是复合键)。而孩子是一个从属表。

    4. 在一个非识别关系中,FK 是一个非 PK 列,并且孩子是独立的(它可能被其他一些关系强制为依赖)。

    5. 所有子类型都具有来自超类型的标识关系。否则它们将不是子类型,它们将独立于超类型。

    6. 所有 1:0-1 的关系都在识别。

所以我做了我认为在我的模型中代表正确的事情。

  • 这可能就是您最终添加[Table]Id密钥的原因。

何时强制(识别)和何时自由(非识别)?

  • 永远不要强迫任何东西重新建模(数据库和函数),尤其是重新数据。我们想要管理、管理、塑造、控制等是无法控制的。但要有效地做到这一点,我们必须首先了解它。当我们强迫它时,我们无法理解任何东西。强迫它剥夺它暴露自己,剥夺我们注意到微妙之处和味道(因为我们“知道”它)。让它自由,但受约束,就像围场里的马,而不是马厩里的囚犯。

    这就是为什么Id在每个电子表格上粘贴列的行为阻碍了对数据的理解,因此也阻碍了对它的任何建模。

  • 如上所述,识别与否是关系;不是实体是否独立,这是一个结果。

做关系/IDEF1X/ERwin 风格:

  1. 你想要一个实体,画一个实体。命名它。除非它是画布上的第一个实体,否则不要添加 keys

  2. 现在考虑它的关系。您已经建模的实体与这个新实体有什么关系?绘制该关系(关系是绘制父子关系)。

  3. 当然,它默认为正在识别,因为(等待它)关系数据库中的大多数关系都是正在识别的。父 PK 放在子 PK 中。

  4. 如果您认为,不,不,我希望这是 Independent,那么您最好有充分的理由。这里的关键问题是,这个实体是否完全独立存在,是否存在于其他独立实体的上下文之外?AFAIC,您的模型中有五个:
    地址
    派对
    项目
    事件
    类型

    每个其他实体仅存在于这些独立实体之一的上下文中。因此,您绘制了识别关系,因此它们都是从属的。

    • 回想一下,我们之前将 Item 设置为 Independent;然后我们有了一个新形式的Item;它制作了旧物品,BandItem;这使得 BandItem 依赖于新项目。

    • 我们在 中有一个很棒的标识符ItemId,它不仅在(当时的)Item 集群中,而且在整个 OrderItem、Review 等中都有。

    • 我们更改了 Item 的上下文(创建了一个更高阶的 Item),并且由于识别关系,然后整个迁移,并且新的 BandItem 在其上下文中迁移。

    • 新的ItemId仍然是一个很好的标识符。BandItemId确实是ItemId,但起着特定的作用,它是 的子集/子类型ItemId

  5. 所以如果它是一个真正的独立实体,那就继续给它一个新的PK。

    • 但是在这个阶段,不是一个Id列,而是一个标识实体的有意义的东西。 Event.Name, Customer.Code. 没有人将客户识别为编号 123456,不,他们会想到“IBM”、“3M”等。稍后,随着模型的进展,我们将确保我们拥有非常好的密钥;现在有了新实体,我们关心它有一个标识符。

    • 例外。对于 Address、Party、Item,您知道在 V1.0 中您将拥有数百万、数千、数千个;这些是将在整个数据库中迁移的主要标识符;真正的PK很长;并且您需要一个简短的代理键作为 PK;所以你从一开始就设置好了,我没有争论。

      • 如果您准备好使用域,那么 INT、INT 或 SMALLINT、SMALLINT。

      • 否则Name,CHAR(30)。

  6. 下一步是完成对新实体的 PK。如果来自 parent 的基数是 1::n,它已经有了 Parent 的 PK,只需添加一个元素使 PK 唯一。让我们看看订单。它已经有了PartId,所以OrderNo可以在里面PartyId。只需将 PK 列的顺序更改为(1) PartyId, (2) OrderNo.

  7. 唯一一次我们做一点强制,是当形成 PK 的列数变得太多,或者 PK 的总宽度变得太宽时,将作为 FK 迁移到子项中。然后,也只有这样,我们才创建一个额外的形式的代理键[Table]Id(它们总是额外的,我们不能失去真正的 PK 或唯一性,因为它支持其他要求)。

    • AFAIC,那个幻数是七(实际上,很多东西的幻数;甚至这个项目也显示为数字七),最大宽度是 30 字节。这是从一开始就使用 Address(已经高度优化)、Party(否则为 64 字节)、Item(超过 30 字节)完成的。

    • 如果我们要打破内在的关系力量,我们需要承受这种关系力量本身非常糟糕的痛苦,并且没有其他原因。在你的模型中甚至没有接近它。

审查集群

你做得很好,所以把它当作下一个进展。基本上你有两个选择,当然我们正在将它与 Item 集群进行比较/关联。

  1. 按原样使用 Review 集群。我们需要一个 SongReview 和一个 AlbumReview。并摆脱 ItemReview(它封装了所有 Items,这意味着我们正在加倍)。我以为我们排除了非乐队项目的评论。

  2. 允许非 BandReview 与任何 BandItem 有关,例如。将 ItemReview FK 从 Item 更改为 BandItem。这将所有 BandItem 封装在 ItemReview 中。摆脱 PerformanceReview。

    • 当然,您可能不希望 BandItem.Other 被审查;可以通过其他方式进行限制。但是如果你想严格,那么你需要(1)。

颜色

很高兴你采用了我的配色方案。

  • 意义,视觉相关性,不会出现在一个微小的模型中(我的大多数模型都在 SO 上);它只显示在较大的模型上,例如您的模型。

  • 因为你用V1.3做得这么好,老师有一个▶苹果给你◀。其实▶IDEF1X Notation◀的文档还是值得再读一遍的,它非常精简,而且我听说人们在建模之后阅读它会获得更多的价值。我需要知道的是,自然层次结构和颜色是否为您做任何事情。

  • 这只是完成了实体级别的逻辑。

您可以继续使用逻辑键级别(唯一的属性是 FK,我们知道它们是什么)。但是请随意开始识别属性(在这种情况下,显示属性级别)。

可选列

U.1) 一个可选的父级已经悄悄回到模型中。PartyAddress is shipped for Order不可为空。

  • 如果您打算将送货地址建模为可选,则需要一个 OrderShipAddress 实体,它是 Order 的子实体,基数为 1::0-1。

    • Nulls(可选列)就像癌症在全身聚集,Nullable FK(可选父项)是五岁之前孤儿的咽喉癌。
      .
  • 这是处理任何可选列的基本方法,不仅限于此处的 FK(可选父级)。

次要的

M.11) 这些在 V1.2
审查中是正确的::评论是 1::0-1
乐队成员::评论是 1:0-n

M.12) Event::Person 是 n::n (并且列不会显示在逻辑级别)

V1.4 和响应

非常好的进展。您对标识符、密钥感到满意吗?

U.8)(如果您先执行此操作,则其余操作将轻松完成。) ERwin 限制。恭喜,您制作的模型已达到 ERwin 在逻辑建模方面的能力限制。需要明确的是,这并不是真正的限制,因为它在物理模型中得到解决,当然它不是 IDEF1X 或关系数据库中的限制。但是现在,在 Logical,它会干扰你的学习和进步。

  • 在 BandItem 中,我们希望 PK 为 (BandItemId, BandId)。但是 ERwin 不允许这样做,因为它说Subtype PK 必须是 Supertype PK 并且只有. 实际上,只要 Supertype PK 是领先的 Identifier,另一个 Identification Relation 是可以接受的。要解决此问题:

    • 删除子类型符号
    • 创建两个识别关系 Item::FloorItem 和 Item::BandItem
  • 我们必须使非识别的关系现在可以是识别的。

  • ERwin 现在会将迁移的 PK 解析为 FK,而不会重复。

  • 是的,将角色重新放入。

U.9) 现在我明白了你想用 Review 集群做什么,所以首先,让我说你已经正确地建模了它,一直到 Rating。

  • 但 Review 本身存在一个基本问题。使用 ReviewerId 的 PK,将只允许一个 Reviewer 进行一次审查。当然,您希望每个乐队/乐队项目的每个评论者都有一个评论,但这在子类型中隐藏得更深。基本上在这里使用 Supertype-Subtype 太严格了。很好理解,在那个早期阶段,但现在我们需要超越它。
    • 代替 Review 集群,创建两个 Review 表,一个 BandReview 和 ItemReview。
    • 关系将是 Person::BandReview 和 Band::BandReview,以及 Person::ItemReview 和 BandItem::ItemReview
    • 然后他们每个人都会有孩子 %Rating, %Comment, %CommentRating。

M.13) Order::OrderShipAddress 是 1::0-1,正确。PartyAddress::Order 是 1::0-n,正确因此送货地址应该是 PartyAddress::OrderShipAddress 1::0-n

M.14) 付款目前每个订单只允许一次付款,这可能是您需要的,但关系是 1::1-n。如果您需要更多,请在 PK 中添加一个 SequenceNo。

M.15) 流派很好。但是 SubGenre 在 PK 中需要一些东西来允许多个流派。我现在将 Genre.Name 更改为 Genre.Genre,并将 SubGenre 添加到 SubGenre PK。- 这也将修复 Event.GenreId。

M.16) 场地现在需要一个 PK 名称。如果您准备好使用更好的键,那么 ShortName 和 Name 作为属性向下移动。

Q.4) 确认。由于我们有一个按顺序识别的关系,并且 PK (PartyId, OrderNo) 因此 OrderNo 是 PartyId 中的一个序列号,对吗?

去 V1.5。包括一些属性。识别它们的最佳方法是启动一个函数模型(现在与它并排使用数据模型)或至少完成所有屏幕的所有函数。

干杯

于 2011-01-29T16:14:37.487 回答