mysql - 创建足够的数据库
问题描述
请在阅读本文时查看附件。谢谢!它纯粹是为视觉输入而创建的
我目前正在为一个项目创建一个数据库,我遇到了这个问题:
我想使用我称为 Doctype 的东西来区分文档的 data_fields。例如,上传合同时,我想使用具有唯一列的特定表。像表 Data_field_1。但是,如果 Doctype 是收据,我希望它使用自定义字段的表 Data_field_2。
我知道这样做会有问题。因此我的问题是:这个问题是否有可能的解决方案?
解决方案
看来您需要实现“表继承”。大约有四种不同的策略可以做到这一点。我将展示最常见的一种,我个人认为它是最灵活和最安全的一种。
我假设您的子表是互斥的,因为这是最常见的情况。例如,您可以这样做:
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
, CONSTRAINTReceipt_ibfk_1
FOREIGN KEY (id
,type
) REFERENCESDocType
(id
,type
))
请参阅DB Fiddle上的运行示例。
推荐阅读
- c - 分叉的孩子不断被终止,状态为 0x008B
- python - 当在 RabbitMQ pika 阻塞连接上调用 process_data_events() 时,“TypeError: heap argument must be a list”
- c# - 如何修复 C# 中由泛型引起的 CS0029 错误
- sql - 如何使用 R 将 data.frame 传递给 SQL“IN”条件?
- javascript - 拇指/指针上的输入范围滑块移动完成火灾事件
- python - 列表索引超出范围(有时失败有时有效)
- google-apps-script - 谷歌表格导入
- macros - 高级符号宏
- jquery - 更新购物车以添加订单项
- bash - bash中域名的最长通用后缀