关于识别关系和多对多关系的数据库设计问题

时间:2012-09-01 05:44:35

标签: mysql database many-to-many identifying-relationship

我有一个奇怪的数据库设计问题,我不确定我是否正确这样做。由于我目前的设计非常复杂,我在下图中简化了它,并使用房屋和占用者(而不是我的实际实体)进行比较。

所以,这是数据库设计的一部分:

标准条件:

  • 多个房子
  • 每个房子多层楼
  • 每层多间卧室

不太标准的条件:

  • 每个人都可以住在多个房子里
  • 每个住户每个房子可以有多间卧室
  • 每个住户每层只能有一间卧室(这是一个棘手的部分)例如,他们可以在1楼有一间卧室,在2楼有一间卧室,在3楼有一间卧室,但是从来没有两间卧室在同一楼层

因此,我想要完成的是这个。在应用设计中,我知道house,我知道floor,我知道occupant。我需要在没有用户指定的情况下查找此信息,bedroom occupant基于这3个条件。有两种解决方案。第一个是在occupants_has_bedrooms表中,我将主键设为occupants_idbedrooms_floors_idbedrooms_floors_houses_id。但是,当我从主键中删除bedrooms_id时,该表不再是与父(bedrooms)的标识关系。这是一种识别关系,因为没有父母就不能存在。因此,有些东西告诉我,我需要将所有四个ID作为主键。我的第二个选择是这三个值之间的唯一索引,但是当我认为我可能正在接近这个错误时。

我如何完成这项工作?

2 个答案:

答案 0 :(得分:1)

这是一个通用的数据库设计策略,并非特定于MySQL,但仍然有用。

很高兴您知道如何查询数据,但不要让它过度影响您的模型(至少在开始时)。

首先要明确的是每张桌子的PK是什么?您看起来正在使用floorsbedrooms的复合键。如果您为除交叉表Occupants_has_bedrooms之外的所有表使用了无信息密钥(每个表的ID列)策略,则会使您的连接更简单。我会假设你可以,所以这里是如何去的:

我要改变的第一件事是摆脱卧室中的floors_house_id列 - 这现在是多余的,可以从连接中获得。

接下来,对occupants_has_bedrooms进行以下更改:

  1. PK for应该只有两列,occupants_id和bedroom_id。 (为什么?因为主键应该只包含足够的信息来唯一标识一行)。
  2. 删除bedrooms_floors_houses_id,由bedrooms_floors_id确定,不需要。
  3. 在(occupants_idbedrooms_floors_id)上添加一个唯一约束,以强制执行“不太标准”的条件。
  4. 最后,对除Occupants之外的所有表执行内连接,在WHERE子句中添加三个条件。这应该可以得到你想要的结果。如果你真的想要复合键,你仍然可以做它切割它变得凌乱。对不起,我不在编辑附近,或者我会为你绘制图表。

答案 1 :(得分:0)

我会设计数据库与你所做的相反。

House
  id
  name
  Floors -- Many to many

Floor
  id
  name
  Bedrooms -- Many to many
  optional: you can have a back pointer to house

Bedroom:
  id
  name
  Occupants -- many to many
  optional : back pointer to floor

Occupant:
  id
  name
  optional : back pointer to Bedroom

现在有了这么多的表,你可以很容易地查询你的情况。