Доступны ли циркулярные ссылки в базе данных?

Когда last_transaction_id

Теоретическая и практическая, любая помощь приветствуется.

database,oracle,circular-dependency,

22

Ответов: 8


11 принят

Записи, которые указывают на другие записи, полезны в базе данных. Иногда эти записи образуют цикл. Это может быть полезно. Единственное реальное раздражение на практике заключается в том, чтобы избежать нарушения ограничений.

Например, если у вас есть таблица пользователя и транзакции, пользователь может иметь указатель на свою последнюю транзакцию. Сначала нужно вставить транзакцию, а затем обновить user.last_transaction_idдо правильного значения. В то время как обе эти записи существуют, вы не можете их стереть, потому что transaction.idточки transaction.user_idи user.idточки last_transaction_id. Это означает, что у пользователя без транзакций есть нуль . Это также означает, что вы должны удалить это поле, прежде чем сможете удалить транзакцию.CREATE TABLE city ( city VARCHAR(32), state VARCHAR(32), PRIMARY KEY (city), FOREIGN KEY (state) REFERENCES state (state) ); CREATE TABLE state ( state VARCHAR(32), captial_city VARCHAR(32), PRIMARY KEY (state), FOREIGN KEY (captial_city) REFERENCES city (city) );

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


20

Рассмотрим города и штаты. Каждый город существует в пределах штата. Каждое государство имеет столицу.

INSERT INTO city (city, state) VALUES ('Miami', NULL);
INSERT INTO state (state, capital_city) VALUES ('Florida', 'Miami');
UPDATE city SET state='Florida' WHERE city='Miami';

Первая проблема. Вы не можете создавать эти таблицы, как показано. Решение состоит в том, чтобы создать их без внешних ключей, а затем добавить внешние ключи.

Вторая проблема: вы не можете вставлять строки в обе таблицы, так как каждая вставка потребует предварительно существующей строки в другой таблице. Решение состоит в том, чтобы установить один из столбцов внешнего ключа как NULL и вставить эти данные в две фазы. например

create table foo_master (
       foo_master_id int not null primary key
      ,current_foo_id int
)


create table foo_detail (
       foo_detail_id int not null primary key
       foo_master_id int not null
)

alter table foo_master
  add constraint fk_foo_current_detail
      foreign key (current_foo_id)
      references foo_detail

alter table foo_detail
  add constraint fk_foo_master
      foreign key (foo_master_id)
      references foo_master

3

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

Если у вас есть такие отношения, как:

create table foo_master (
       foo_master_id int not null primary key
)


create table foo_detail (
       foo_detail_id int not null primary key
       foo_master_id int not null
       is_current char (1)
)

alter table foo_detail
  add constraint fk_foo_master
      foreign key (foo_master_id)
      references foo_master

Тогда удаление записи может вызвать такую ??проблему с курицей и агг из-за круговых зависимостей.

Лучшая схема для этого выглядит так:

NOCYCLE

Это означает, что связь не является циклической, и текущая запись foo_detail все еще может быть идентифицирована.


3

Одно из последних дополнений к синтаксису иерархического запроса Oracle - ключевое слово - было сделано специально для этой цели - для обработки циркулярных ссылок в данных. Я не вижу в этом ничего плохого, и раньше мне приходилось иметь дело с подобной моделью. Это не так сложно, особенно в Oracle, который поддерживает отложенные ограничения.


1

Циркулярные ссылки следует избегать, как чума. Можно настроить двусторонние отношения или даже отношения к себе (если вы были таблицей), но круговая зависимость просто требует неприятностей.

базы данных, Oracle, круговая зависимость,
Похожие вопросы
Яндекс.Метрика