表定义中的多引用外键?

时间:2010-02-04 20:33:11

标签: sql sqlite foreign-keys

摘要

如何让非程序员轻松编写如下查询?

select
    table_name.*
  , foreign_table_1.name
  , foreign_table_2.name
from
  table_name
left outer join foreign_table foreign_table_1 on foreign_table_1.id = foreign_1_id
left outer join foreign_table foreign_table_2 on foreign_table_2.id = foreign_1_id
;

上下文

我有这样的情况:

create table table_name (
    id integer primary key autoincrement not null
  , foreign_key_1_id integer not null
  , foreign_key_2_id integer not null
  , some_other_column varchar(255) null
);

create table foreign_table (
    id integer primary key autoincrement not null
  , name varchar(255) null
);

...其中foreign_key_1_idforeign_key_2_id都引用foreign_table。 (显然,这是简化和抽象的。)要查询并获取相应的值,我可能会这样做:

select
    table_name.*
  , foreign_table_1.name
  , foreign_table_2.name
from
  table_name
left outer join foreign_table foreign_table_1 on foreign_table_1.id = foreign_1_id
left outer join foreign_table foreign_table_2 on foreign_table_2.id = foreign_1_id
;

(也就是说,联接中的别名foreign_table可以正确链接。)这很好用。但是,我的一些客户希望使用SQL Maestro来查询表。该程序使用外键信息使用相当简单的接口(“Visual Query Builder”)链接表。例如,用户可以选择多个表,SQL Maestro将填充连接,如下所示:

Visual Query Builder http://sqlmaestro.com/data/912/1183273856-250x238.png

(这是他们网站上的图表,仅供参考。)

只要外键仅引用一个表,此策略就可以正常工作。多参考情况似乎令人困惑,因为它像这样打喷嚏:

SELECT 
  table_name.some_other_column,
  foreign_table.name
FROM
  table_name
  INNER JOIN foreign_table ON (table_name.foreign_key_1_id = foreign_table.id)
  AND (table_name.foreign_key_2_id = foreign_table.id)

...因为外键定义如下:

create table table_name (
    id integer primary key autoincrement not null
  , foreign_key_1_id integer not null
  , foreign_key_2_id integer not null
  , some_other_column varchar(255) null

  ---------------------------
  -- The part that changed:
  ---------------------------
  , foreign key (foreign_key_1_id) references foreign_table(id)
  , foreign key (foreign_key_2_id) references foreign_table(id)
);

create table foreign_table (
    id integer primary key autoincrement not null
  , name varchar(255) not null
);

这是一个问题,因为你只返回1 foreign_table.name个值,而通常有两个不同的值。

问题

我如何定义外键来处理这种情况? (这样做是否可行或有意义?我不认为这会对约束检查产生很大影响,所以我认为这是我无法找到任何信息的原因。)我的结局目标是让我的客户自己轻松查询这些信息,虽然这种情况不会每天都发生,但每次出现时都必须帮助人们完成这项工作,这是非常耗时/令人沮丧的。

如果没有办法以这种方式解决我的外键问题,你能提出任何其他选择吗?我已经有了一些方法可以通过视图向人们提供这些信息,但人们通常需要比这更灵活。

1 个答案:

答案 0 :(得分:2)

在我看来,你的定义很好,并且SQL Maestro错误地将同一个表中的两个外键解释为相同的外键,因此我会提醒他们这个事实,以便他们可以修复它。