Postgres多个表的外键

时间:2014-05-26 08:16:14

标签: sql postgresql foreign-keys

我有以下概念性问题,但我还没有能够提出令人满意的解决方案。 我将以一个例子解释它。

我有两个表catsdogs,它们由不同的属性组成(它们需要是不同的表,因为我的实际案例实际上更复杂)。 我可以喂这些动物'我想跟踪有关此喂食操作的一些信息(例如[animal_fed]food_typefood_quantitydate,...)。

到目前为止,我使用的feeds表格包含以下架构:animal_id INTEGERtable_name VARCHAR(50)(可能是"cats""dogs",但会有更多的物种..),[other fields]

我对这个解决方案完全不满意因为它使得它成为一种痛苦(如果可能的话,但必须有一种方式......)select from feeds检索动物被喂食的一些信息(同样到join)。

我怎样才能更好地解决这个问题?

使用父母'表代表了一个很好的解决方案?

或者,如果您认为我的实际方法很好,我怎样才能"join"获取所有feeds信息以及动物name

谢谢。

2 个答案:

答案 0 :(得分:0)

有几种方法可以改进它,但你的解决方案几乎是好的:

  1. 将所有动物放在一张桌子上。你说他们需要不同,但也许你可以合并它们。最终animas表将包含两个表中的所有列。您将拥有列animal_type,它将是 dog cat
  2. 多个SQL查询。您可以保留所有内容并制作一些方法/函数来获取所需的数据。进行查询以获取所有Feed ,然后在另一个查询中,您可以获取这些动物。如果要限制查询,可以添加条件FROM animals WHERE id IN ( ANIMAL_ID_FROM_PREVIOUS_RESULT )。然后你必须在你的应用程序中合并它们。
  3. 您可以创建两个关系表。您将animals表放在feeds表中,然后创建r_dog_feedr_cat_feed。他们将feed_id引用feeds表格,然后引用dog_idcat_id。然后,您可以使用UNION
  4. 编写SQL

    SELECT dogs.name as name,food。* FROM r_dog_feed     在dogs.id = r_dog_feed.dog_id上加入狗     JOIN Feed on feeds.id = r_dog_feed.feed_id 联盟 选择cats.name作为名称,食物。* FROM r_cat_feed     JOIN catsON dogs.id = r_cat_feed.cat_id     JOIN Feed on feeds.id = r_cat_feed.feed_id

答案 1 :(得分:0)

如果你不能将猫和狗的数据放在同一张桌子上,那么另一个好的解决方案就是拥有一张能够保存猫狗常用数据的动物表。然后,您可以在动物和猫之间以及动物和狗之间建立一对一或一对一的关系。

在动物身上添加一个animal_type,告诉您在哪个其他表格中可以找到特定的额外信息。

在猫和狗上,你将带有FK的animal_id添加到动物桌上。

在饲料中,您将animal_id和FK添加到动物表中。

<强>赞成

您可以轻松处理饲料和动物之间的关系。 SQL只需要访问常见的动物信息就很容易编写。

某些应用程序框架确实支持“继承的”数据子类型,并为您处理大部分内容。但是,既然你没有说明你的申请用途,我不确定是否适用。

<强>缺点

您不能仅使用数据库约束来强制执行完整性。您将需要触发器或应用程序逻辑来保证没有猫或狗引用相同的animal_id,并且每只动物都是猫或狗(如果这是您的要求之一)。

当您需要访问cat and dog额外信息时,您可能需要单独的SQL语句,因为结构不同,并且对数据的访问必须使用不同的表。

如果您需要添加其他动物类型,您将添加表格...并添加不同的SQL来访问额外信息...这不是很好,可能会失控。