需要数据库设计指导

时间:2010-07-19 16:40:31

标签: sql database database-design erd

一位兼职漫画家的奶农也有几头奶牛。他将每头牛分配给一个特定的牛群。在每个牛群中,农民都有一头他最喜欢的牛 - 通常是牛在动画片中的特色。每个牛群中的一些不满,主要是那些认为应该出现在卡通片中的人,不同意农民对最喜欢的牛的选择,他们贬低地称之为神圣的牛。结果,每个群体现在都选出了一个牧群领袖。

这就是我认为表格应该是什么样的,如果可以做得更好,你可以告诉我吗?到目前为止,我正在使用喜欢的表做多对多,因为中间是最好的解决方案,也不需要SQL语句,这只是出于设计目的。

提前谢谢

Table Herd           Table Favorite               Table Cartoon   Table Cow
PK herdID          Intermediate Table             PK cartoonID     PK cowID
   herdname                                          cartoonTitle     cowName
   herdleader                                        cartoonType
                                                     cartoonDate

编辑图片@ 3:01 pmEST这是正确的吗?

cowErd http://img838.imageshack.us/img838/1268/capture3h.png

添加了新图片@ 8:57 am 7/20/2010可以请一位人士批评这个ERD Erd2 http://img37.imageshack.us/img37/5794/capture3fc.png

添加新图片@ 12:47 pm 7/20/2010除非有任何异议,这是每个马克的解释的最终草案 mark ERD http://img651.imageshack.us/img651/691/capture4b.png

5 个答案:

答案 0 :(得分:5)

迈克尔:

问题陈述中的名词是什么,有多少名词?

Farmer  - There is one farmer
Cow     - There are many cows
Herd    - There are many herds
Cartoon - There are many cartoons

由于只有一位农民,所以请将他从未来的讨论中删除。这些是你的基础 实体。

每个实体有哪些属性?

Cow     - each cow has a name
        - each cow is a member of a herd
Herd    - each herd has a name
        - each herd has a cow that is the sacred cow
        - each herd has a cow that is the herd leader
Cartoon - each cartoon has a name
        - each cartoon may have a cow that appears in it 
             (not specified definitively)

所以这些属性中的一些引用其他引用,而有些则不引用。不引用其他基本实体的属性很简单。其他的需要更多的考虑。

Can a cow be a member of more than one herd?
Must a cow be a member of a herd?
Can a herd have more than one cow that is the sacred cow?
Must each herd have a cow that is the sacred cow?
Can a herd have more than one cow that is the herd leader?
Must each herd have a cow that is the herd leader?

这些问题有助于概述实体之间的关系是强制性的还是可选的,以及这些关系是一对多还是多对多。

答案 1 :(得分:4)

一个讨论项目,所以我把它作为社区Wiki。

关系模型做得不好的一件事是强制执行在牧群级别持有的SacredCow和HerdLeader实际上指向那些牧群成员的奶牛。

说你的牧群是明星和十字架。 “Star”牧群的细节可能会让Rigel成为SacredCow和Castor作为HerdLeader,但是'Cow'表可能会将Castor视为'Cross'Herd的成员。在实践中,当你创造一个新的牧群时,你要面对一个鸡和鸡蛋的情景,当你有一个没有奶牛的牧群(因此没有牧羊人/神圣的牧羊犬)或没有牧群的牛。

另一种模型会有'Cow'表格,表明特定的牛是HerdLeader和/或SacredCow。 [在一个物理实现中,有一个独特的约束可以强制执行每个Herd只有一头是SacredCow的母牛和一头是HerdLeader的母牛。]。“Herd”表没有SacredCow或HerdLeader 。这种模式无法强制每个群体都有一个HerdLeader和一个SacredCow。

两者都是模特。两者都有缺陷。在逻辑层面,我可能会选择前者,因为它更加规范化。在物理上,我会考虑哪种不一致会更麻烦,更有可能发生,我会选择最能阻止它的模型。

答案 2 :(得分:1)

我喜欢你真的试图自己做这件事。 事实上,你几乎就在那里,所以你根本没做错。

让我们从对象/实体角度来看这个。

实体包括以下内容:

  • 奶牛
  • 畜群
  • CowHerds(你必须将一头牛与听到的人联系起来)
  • CowCartoon(其中一头奶牛是最喜欢的,你总是可以通过使用这个奶牛上链引用这头牛的声音)

奶牛

  • CowID(主键)
  • CowName(varchar, 这可能是关键但是 牛可能有相同的名字吗?)

畜群

  • HerdID(主键)
  • HerdName(这也可能是主键, 最终这是你的决定)
  • CowID(外键,请记住每个牛群都有牛头,你甚至可以在另一张桌子上分开,但这真的不值得。)

牧牛

  • CowID(fK to cows)
  • HerdID(fk to heards)

上述字段的组合用作主键

CowCartoon

  • CartoonID(卡通的主键)
  • CowID('最喜欢'的牛,参考哪个牛农民会写一个卡通片)
  • 发布日期(发布日期)
  • 标题 ....

如评论中所述,您还可以摆脱CowHerds表并直接在Cows表中引用HerdID。

答案 3 :(得分:1)

第1部分。

如果以下情况属实:

each Cow must be in exactly one Herd
a Herd must have a sacredCow and a herdLeader
a sacredCow for a Herd must be a Cow in that Herd
a herdLeader for a Herd must be a different Cow in that Herd

然后您可以使用此部分模型实现这些规则:

Cow (cowID, herdID) (all mandatory columns)
- primary key (cowID)
- unique (herdID, cowID)
- foreign key (herdID) references Herd (herdID)

Herd (herdID, sacredCow, herdLeader) (all mandatory columns)
- primary key (herdID)
- foreign key (herdID, sacredCow) references Cow (herdID, cowID)
- foreign key (herdID, herdLeader) references Cow (herdID, cowID)
- constraint (sacredCow != herdLeader)

注意FK关系如何包含herdID,而不仅仅是cowID。这样可以确保只有牧群中的那些母牛可以成为牧群的神圣牧群或牧群领袖。

这种设计使实施起来有点棘手,但并非不可能。 Herd上的外键必须在像Oracle这样的数据库中可以推迟,因为我们需要能够在为Cows插入行之前为Herd插入行,而Herd需要至少两个Cows( sacredCow和牧群领袖。

第2部分。

下一个挑战是实施以下约束:

only a Sacred Cow may be featured in a Cartoon

这样做的一种方法可能是将Cows分成两个独立的关系:SacredCows和NonSacredCows。

SacredCow (sacredCowID, herdID) (all mandatory columns)
- primary key (sacredCowID)
- unique (herdID, sacredCowID)
- foreign key (herdID) references Herd (herdID)

NonSacredCow (nonSacredCowID, herdID) (all mandatory columns)
- primary key (nonSacredCowID)
- unique (herdID, nonSacredCowID)
- foreign key (herdID) references Herd (herdID)

Herd (herdID, sacredCow, herdLeader)
- primary key (herdID)
- foreign key (herdID, sacredCow) references SacredCow (herdID, sacredCowID)
- foreign key (herdID, herdLeader) references NonSacredCow (herdID, nonSacredCowID)

Cartoon (cartoonID, featuredCow) (all mandatory columns)
- primary key (cartoonID)
- forign key (featuredID) references SacredCow (sacredCowID)

(在这种设计中,不再需要约束(sacredCow!= herdLeader),因为根据定义它们现在是不同的奶牛。)

答案 4 :(得分:1)

假设奶牛一次只能属于一个牛群并且假设不止一头牛(显然来自不同的牛群)可以出现在同一个卡通片中,我的建议是:

表群

Herd ID (PK)
Herd Name

Table Cow

Cow ID (PK)
Herd ID (FK)
Cow Name
Is Leader (Boolean)
Is Sacred (Boolean)

表卡通

Cartoon ID (PK)
Cartoon Title
Cartoon Type
Cartoon Date

表格外观

Cow ID (PK)
Cartoon ID (PK)