Внешние ключи с множественными ссылками в определении таблицы? - PullRequest
1 голос
/ 04 февраля 2010

Резюме

Как сделать так, чтобы непрограммисты могли написать запрос, подобный следующему?

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_id и foreign_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
(источник: sqlmaestro.com )

(это диаграмма с их сайта, просто для иллюстрации.)

Эта стратегия прекрасно работает, если внешние ключи ссылаются только на одну таблицу. Ситуация с множественными ссылками, кажется, сбивает с толку, потому что это скрежетает SQL следующим образом:

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 значение, тогда как часто есть 2 отдельных значения.

Вопрос

Как мне определить внешние ключи, чтобы справиться с этой ситуацией? (Возможно ли это или имеет смысл сделать это? Я не думаю, что это будет иметь большое значение при проверке ограничений, поэтому я подумал, что по этой причине я не могу найти какую-либо информацию.) Мой конец цель состоит в том, чтобы сделать запрос этой информации легким для моих клиентов, и, хотя такая ситуация случается не каждый день, отнимает много времени / расстраивает необходимость помогать людям проходить через нее каждый раз, когда она появляется.

Если нет способа решить мою проблему с внешним ключом, можете ли вы предложить какие-либо альтернативы? У меня уже есть несколько способов получить от людей эту информацию через представления, но людям часто требуется больше гибкости, чем эта.

1 Ответ

2 голосов
/ 04 февраля 2010

Мне кажется, что ваше определение в порядке, и SQL Maestro неправильно интерпретирует два внешних ключа для одной и той же таблицы как один и тот же внешний ключ, поэтому я бы предупредил их об этом факте, чтобы они могли это исправить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...