首页 > 解决方案 > 创建足够的数据库

问题描述

请在阅读本文时查看附件。谢谢!它纯粹是为视觉输入而创建的

我目前正在为一个项目创建一个数据库,我遇到了这个问题:

我想使用我称为 Doctype 的东西来区分文档的 data_fields。例如,上传合同时,我想使用具有唯一列的特定表。像表 Data_field_1。但是,如果 Doctype 是收据,我希望它使用自定义字段的表 Data_field_2。

我知道这样做会有问题。因此我的问题是:这个问题是否有可能的解决方案?

在此处输入图像描述

在此处输入图像描述

标签: mysqlforeign-keysprimary-key

解决方案


看来您需要实现“表继承”。大约有四种不同的策略可以做到这一点。我将展示最常见的一种,我个人认为它是最灵活和最安全的一种。

我假设您的子表是互斥的,因为这是最常见的情况。例如,您可以这样做:

create table Documentation (
  id int primary key not null,
  title varchar(100)
);

create table DocType ( -- this is the parent table
  id int not null,
  type char(1) not null check (type in ('c', 'r', 's', 'o')),
  data_field int,
  name varchar(50),
  primary key (id, type),
  foreign key (data_field) references Documentation (id)
);

create table Contract ( -- this is a child table "Contract"
  id int not null,
  type char(1) not null check (type = 'c'),
  start_date date,
  end_date date,
  primary key (id, type),
  foreign key (id, type) references DocType (id, type)
);

create table Receipt ( -- this is a child table "Receipt"
  id int not null,
  type char(1) not null check (type = 'r'),
  buyer varchar(20),
  seller varchar(20),
  primary key (id, type),
  foreign key (id, type) references DocType (id, type)
);

然后,您可以尝试插入一些数据:

insert into Documentation (id, title)
  values (123, 'First Document');

insert into DocType (id, type, data_field, name)
  values (1001, 'c', 123, 'Contract #1');  

insert into Contract (id, type, start_date, end_date)
  values (1001, 'c', '2020-01-01', '2020-12-31');

最后,我尝试为无法工作的相同 DocType 插入“收据”(如预期的那样),因为我们强制执行排他性:

insert into Receipt (id, type, buyer, seller) 
  values (1001, 'r', 'buyer1', 'seller2');

错误:ER_NO_REFERENCED_ROW_2:无法添加或更新子行:外键约束失败 ( test. Receipt, CONSTRAINT Receipt_ibfk_1FOREIGN KEY ( id, type) REFERENCES DocType( id, type))

请参阅DB Fiddle上的运行示例。


推荐阅读