我应该如何在表之间建立关系?

djmepvbi  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(390)

我正在我的web应用程序中构建一个发票组件。在我的模式中,我们有一些特定客户可能想要发票的级别。

Projects -> Sites -> Jobs -> Phases -> Teams

这些表中的每一个都是数据库中的表,并且都与其父表有关系。
我计划构建一个items表,该表将保存关于如何为每个级别的工作开具发票的一般信息,即名称、默认价格、度量单位等。
然后,用户将创建一个发票模型,他们可以将项目列表与之关联,以便这些项目可以重用。
这就是我的问题发挥作用的地方。当是时候发票,我需要相关的发票模型,以上述一个级别。我不想为这些级别中的每一个创建一个到发票模型的链接表。我希望以某种方式保持表之间的关系完整性。但是,如果将来有什么东西我可以反对的话,我不想为了考虑到这个新的“计费级别”而进行巨大的数据库更改和/或代码更改。
有没有一种方法可以让我保持关系的完整性,而不必创建一个新表来将开票模型链接到级别?

ycl3bljg

ycl3bljg1#

可以实现多态关系,解决附加不同实体类型的“n”个数的问题。
多态关系的缺点是,据我所知,实现时不可能不损失引用完整性。
好好读一读https://hashrocket.com/blog/posts/modeling-polymorphic-associations-in-a-relational-database. 多态连接是一种流行且最简单的实现,引用自以下文章:
多态连接
将acl连接到资源的一种简单方法是在acl表上使用两列:resource\ type和resource\ id。acl表可以定义如下:

create table acl(
  id serial primary key,
  resource_type varchar not null,
  resource_id integer not null,
  -- other fields omitted
  unique(resource_id, resource_type)
);

检索文档id:42的acl的查询如下所示:

select *
from acl
where resource_type='document'
  and resource_id=42;

这种方法的一个严重问题是,由于缺少外键约束,数据库可以执行的数据完整性非常有限。它可以确保一个资源没有更多的acl,但仅此而已。资源可能缺少acl,acl可能指向缺少的资源。
exclusive-belowns-to方法是增加引用完整性的好方法,但是对于每个可能的实体类型都需要一个新的列。引自文章:
exclusive allown to(aka exclusive arc)在这个模型中,acl对它所属的所有表都有外键。

create table acl(
  id serial primary key,
  document_id integer references document,
  image_id integer references image,
  file_id integer references file,
  report_id integer references report,
  -- other fields omitted
  check(
    (
      (document_id is not null)::integer +
      (image_id is not null)::integer +
      (file_id is not null)::integer +
      (report_id is not null)::integer 
    ) = 1
  )
);

create unique index on acl (document_id) where document_id is not null;
create unique index on acl (image_id) where image_id is not null;
create unique index on acl (file_id) where file_id is not null;
create unique index on acl (report_id) where report_id is not null;

注意check约束。这确保了acl只属于任何类型的一个资源。使用此设计,acl不能孤立,但无法强制资源具有acl。部分唯一索引也很重要。将唯一索引限制为不允许空值可以极大地节省空间并减少insert上的写操作。

guz6ccqo

guz6ccqo2#

为了清楚地回答您的问题,如果不创建至少另外两个表(一个用于存储模型和项目之间的关系ID,另一个用于存储要创建的项目的所有数据),就无法保持关系完整性,在这种情况下,您将只会得到另外两个表,但将来的痛苦现在就可以解决了。

相关问题