fis*_*est 26
考虑城市和州.每个城市都在一个州内.每个州都有一个首都.
CREATE TABLE city (
city VARCHAR(32),
state VARCHAR(32) NOT NULL,
PRIMARY KEY (city),
FOREIGN KEY (state) REFERENCES state (state)
);
CREATE TABLE state (
state VARCHAR(32),
capital_city VARCHAR(32),
PRIMARY KEY (state),
FOREIGN KEY (capital_city) REFERENCES city (city)
);
Run Code Online (Sandbox Code Playgroud)
第一个问题 - 您无法如图所示创建这些表.解决方案是在没有外键的情况下创建它们,然后添加外键.
第二个问题 - 您无法在任何表中插入行,因为每个插入都需要在另一个表中预先存在的行.解决方案是将其中一个外键列设置为NULL,并将该数据分两个阶段插入.例如
--Create state record
INSERT INTO state (state, capital_city) VALUES ('Florida', NULL);
--Create various city records
INSERT INTO city (city, state) VALUES ('Miami', 'Florida');
INSERT INTO city (city, state) VALUES ('Tallahassee', 'Florida');
INSERT INTO city (city, state) VALUES ('Orlando', 'Florida');
--Set one of the cities as the capital
UPDATE state SET capital_city = 'Tallahassee' WHERE state = 'Florida';
Run Code Online (Sandbox Code Playgroud)
Mr.*_* 安宇 14
指向其他记录的记录在数据库中很有用.有时这些记录形成一个循环.这可能仍然有用.实践中唯一真正的烦恼是避免违反限制.
例如,如果您有用户和事务表,则该用户可能具有指向其上一个事务的指针.您需要先插入事务,然后将其更新last_transaction_id为正确的值.虽然这两个记录都存在,但你无法删除它们,因为user.last_transaction_id要点transaction.id和transaction.user_id指向user.id.这意味着没有事务的用户具有null last_transaction_id.这也意味着您必须先删除该字段,然后才能删除该事务.
管理这些外键约束是一种痛苦,但它肯定是可能的.如果稍后向数据库添加约束会引入新的循环依赖关系,则可能会出现问题.在这种情况下你必须要小心.但是,只要循环中的一个记录具有可空的外键字段,就可以中断循环并删除记录.只要您按正确的顺序插入记录,更新通常不是问题.
这在技术上是可行的,但在删除记录时可能会导致各种问题,因为它会产生先有鸡还是先有蛋的问题。这些问题通常需要采取激烈的措施来解决,例如手动删除 FK 并删除有问题的项目。
如果你们有这样的关系:
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
Run Code Online (Sandbox Code Playgroud)
然后,由于循环依赖,删除一条记录可能会导致这样的鸡和聚合问题。
更好的架构如下所示:
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
Run Code Online (Sandbox Code Playgroud)
这意味着该关系是非循环的,并且仍然可以识别“当前”foo_detail 记录。
Oracle 分层查询语法的最新添加之一 -NOCYCLE关键字 - 专门用于此目的 - 处理数据中的循环引用。我没有发现它有什么问题,并且之前不得不处理这种模型。这并不太难,尤其是在支持延迟约束的 Oracle 中。