sql - 具有来自不同表的多列的外键

标签 sql database database-design foreign-keys multiple-tables

举个愚蠢的例子:我有很多家养动物,每只都有 NAME 作为 id 和类型(是 CAT 或 DOG),让我们这样写(伪代码):

TABLE ANIMALS (
  NAME char,
  ANIMAL_TYPE char {'DOG', 'CAT'}
  PRIMARY KEY(NAME)
)

(例如,我有一只名叫 Felix 的猫和一只名叫 Pluto 的狗)

在另一张 table 上,我想为我的每只动物存储喜欢的食物:

TABLE PREFERED_FOOD (
  ANIMAL_NAME char,
  PREF_FOOD char
  FOREIGN KEY (ANIMAL_NAME) REFERENCES ANIMALS(NAME)
)

(比如,Felix 喜欢牛奶,Pluto 喜欢骨头)

因为我想定义一组可能的首选食物,所以我在第三张表中存储了每种动物的食物类型:

TABLE FOOD (
  ANIMAL_TYPE char {'DOG', 'CAT'},
  FOOD_TYPE char
)

(例如,狗吃骨头和肉,猫吃鱼和牛奶)

我的问题来了:我想在 PREFERED_FOOD 中添加一个外部约束,因此 PREF_FOOD 是来自具有 FOOD.ANIMAL_TYPE=ANIMALS.TYPE 的 FOOD 的 FOOD_TYPE。如何在不复制 PREFERED_FOOD 上的 ANIMAL_TYPE 的情况下定义此外键?

我不是 SQL 专家,所以如果它真的很容易,你可以说我愚蠢;-)

最佳答案

你不能在 SQL 中。如果 SQL 支持断言,我认为您可以。 (SQL-92 标准定义了断言。据我所知,还没有人支持它们。)

要解决该问题,请使用重叠约束。

-- Nothing special here.
create table animal_types (
  animal_type varchar(15) primary key
);

create table animals (
  name varchar(15) primary key,
  animal_type varchar(15) not null references animal_types (animal_type),
  -- This constraint lets us work around SQL's lack of assertions in this case.
  unique (name, animal_type)
);

-- Nothing special here.
create table animal_food_types (
  animal_type varchar(15) not null references animal_types (animal_type),
  food_type varchar(15) not null,
  primary key (animal_type, food_type)
);

-- Overlapping foreign key constraints.
create table animals_preferred_food (
  animal_name varchar(15) not null,
  -- This column is necessary to implement your requirement. 
  animal_type varchar(15) not null,
  pref_food varchar(10) not null,
  primary key (animal_name, pref_food),
  -- This foreign key constraint requires a unique constraint on these
  -- two columns in "animals".
  foreign key (animal_name, animal_type) 
    references animals (animal_name, animal_type),
  -- Since the animal_type column is now in this table, this constraint
  -- is simple.
  foreign key (animal_type, pref_food) 
    references animal_food_types (animal_type, food_type)
);

关于sql - 具有来自不同表的多列的外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12573099/

相关文章:

sql - 表左连接时 "where"子句和 "on"子句有什么区别?

sql - 尝试根据另一个参数获取数据统计信息

sql - Postgresql 在一列或大表中获取一组唯一值的最快方法

mysql - 保存 SQL 语句的结果以在别处使用

ruby-on-rails - rails 字段验证是否

SQL表设计帮助

mysql - 是否可以使用 MySQL 的模型/架构进行复杂查询?

mysql - 在 MySql 中,将结果行从查询转换为逗号分隔的字符串

sql - 我需要做什么才能读取列中的日期?

mysql - 查找表的最佳 mysql 表类型(重读,无写)