首页 > 解决方案 > 数据库结构:如何根据“祖父”表定义表中键的唯一性?

问题描述

很难表达问题标题,因为我缺乏我想要实现的术语,所以我会用我想要做的精确示例来写它。

有这些表:

Table market{
  id integer [pk]
  code varchar(32) [not null, unique]
  name varchar(32) [not null]
}

Table outcome{
  id integer [pk]
  market integer [not null, ref: > market.id]   # References market
  code varchar(32) [not null, unique]
  name varchar(32) [not null]
}

Table game{
  id integer [pk]
  match integer [not null, ref: > match.id]     # References match
  outcome integer [not null, ref: > outcome.id] # References outcome
  odd float [not null]
  status integer [not null, ref: > status.id]
  won bool [null]
}

如何在表中添加唯一键以确保game只有outcome每个(“祖父关系”)具有值?marketmatchnot null

例如

market table
-------------------+
id | code | name   |
-------------------+
1  | vict | Victory|
1  | goal | Goals  |
-------------------+

outcome table
------------------------------------+
id | market | code | name           |
------------------------------------+
1  | 1      | home | Home           |
2  | 1      | away | Away           |
3  | 2      | one  | One            |
4  | 2      | two  | Two            |
5  | 3      | thmr | Three or More  |
------------------------------------+

game table
-------------------------------------------+
id | match | outcome | odd | status | won  |
-------------------------------------------+
1  | 1     | 1       | 1.2 | 1      | NULL |
2  | 1     | 2       | 2.5 | 1      | 1    | // OK
3  | 2     | 1       | 1.7 | 1      | 1    | 
4  | 2     | 2       | 2.4 | 1      | 1    | // ERROR
-------------------------------------------+

标签: sqldatabasedatabase-designforeign-keysunique-index

解决方案


大多数数据库允许过滤唯一索引或类似的东西。

create unique index unq_game_market_match
    on game(market, match)
    where outcome is not null;

在那些没有的情况下,您可以对计算列和/或函数索引执行类似的操作。


推荐阅读