SQL'de bir elektrik şemasını modellemekte bir sorunla karşılaştım. Yakalamak istediğim yapı
part ←────────── pin
↑ ↑
part_inst ←───── pin_inst
burada "inst", "örnek" in kısaltmasıdır.
Örneğin, 1OUT, 1IN-, 1IN +, GND, 2IN +, 2IN-, 2OUT ve V CC'ye sahip part
bir LM358 op-amp olarak sahip olabilirim . Daha sonra bu parçayı şemaya yerleştirerek a ve 8
s oluşturabilirim .pin
part_inst
pin_inst
Veri alanlarını yok sayarak, bir şemadaki ilk denemem şuydu:
create table parts (
part_id bigserial primary key
);
create table pins (
pin_id bigserial primary key,
part_id bigint not null references parts
);
create table part_insts (
part_inst_id bigserial primary key,
part_id bigint not null references parts
);
create table pin_insts (
pin_inst_id bigserial primary key,
part_inst_id bigint not null references part_insts,
pin_id bigint not null references pins
);
Bu şema ana sorunu bir olmasıdır pin_inst
bir bağlı olabilir part_inst
ile part_id=1
ancak onun pin
sahiptir part_id=2
.
Bu sorunu uygulama düzeyi yerine veritabanı düzeyinde önlemek istiyorum. Yani, birincil anahtarlarımı bunu zorlayacak şekilde değiştirdim. Değişen çizgileri ile işaretledim --
.
create table parts (
part_id bigserial primary key
);
create table pins (
pin_id bigserial, --
part_id bigint not null references parts,
primary key (pin_id, part_id) --
);
create table part_insts (
part_inst_id bigserial, --
part_id bigint not null references parts,
primary key (part_inst_id, part_id) --
);
create table pin_insts (
pin_inst_id bigserial primary key,
part_inst_id bigint not null, --
pin_id bigint not null, --
part_id bigint not null references parts, --
foreign key (part_inst_id, part_id) references part_insts, --
foreign key (pin_id, part_id) references pins --
);
Bu yöntemle benim tutkum, birincil anahtarları kirletmesidir: atıfta bulunduğum her yerde part_inst
, hem part_inst_id
ve hem de izlemem gerekiyor
part_id
. pin_inst.part_inst.part_id = pin_inst.pin.part_id
Aşırı ayrıntılı olmadan kısıtlamayı uygulamaya koymanın başka bir yolu var mı
?
pin_inst_id
Artıklık olanı da kaldırabilirsiniz .(part_inst_id, part_id, pin_id)
Birincil anahtarı olarak kullanabilirsiniz .