繁体   English   中英

如何设计包含公司和简单客户的关系数据库

[英]How to design relational database which contains companies and simple customers

我必须为组织会议的公司设计数据库模式。 在这些会议中可以参与私人客户或其他公司(每家公司都可以注册少数人)。 目前,我需要一些关于如何将以前提到的客户保留在数据库中的建议。 我想到了三种方式:

  1. 将它们保存在一个名为Customers表中,对于私人客户,将字段留空(如company_name等)。 我想这是最糟糕的主意。
  2. 创建两个表: private_customercompany_customer ,但似乎这些表通常会保持连接状态,因此可能会导致性能问题。
  3. customers创建一个表,并通过customer_type类的方法区分它们。 然后创建另一个包含客户类型的表,依此类推。 我想这是最好的选择。 @编辑

为了更好地理解,我将写下简短的摘要:

有些公司组织会议(每次会议可能需要几天时间)。 客户应通过www网站注册这些会议。 作为客户,我们了解个人或公司,但会议的参与者是人(公司可以注册许多人)。 公司代表可以在会议开始日期前两周保留许多座位并提供有关参与者的信息。

我会感谢每一个提示或其他设计。 如果你能告诉我关于设计数据库模式的一些资料,那将是很好的。 提前致谢,

马里乌什。

我首先要用更精确的语言重述这些要求。

  • 会议有很多参与者。
  • 会议有很多客户。
  • 客户可以是个人参与者,也可以是公司的代表。
  • 所有参与者都是客户。
  • 客户预订0个或更多会议。
  • “公司”类型的客户可以为多个参与者创建预订。
  • 公司类型的客户可以为已知或未知参与者创建预订。
  • 所有参与者必须在会议开始日期前2周知晓。

(未说明,但假设)

  • 客户可以预订多个会议。
  • 客户可以为会议预留多个预约。
  • 随着时间的推移,与会者可能属于多个客户(例如,一个人可能会参加几个公司的不同会议)。

这导致了以下行的架构:

Conference
------------
ConferenceID (pk)
StartDate
EndDate

Client
---------
ClientID (PK)
ClientType (Company or Individual)

Reservation
------------
ClientID (FK)
ConferenceID (FK)
NumberOfAttendees 

ConferenceAttendee
-------------
AttendeeID (FK)
ClientID (FK)
ConferenceID (FK)
ConfirmationDate

Attendee
-------------
AttendeeID (PK)

然后,您可以创建只有“公司”类型的客户可以为多个与会者预订的支票,不会创建会议开始日期后不到2周的确认日期的ConferenceAttendee记录。

重要的想法是组织和个人并不完全相同,但他们并不完全不同。 两者都可以有姓名,地址和电话号码,两者都可以参加会议。

对于这种事情有各种搜索术语,包括“独占弧”和“超类型/子类型”。 我为PostgreSQL写了这个最小的例子,但它主要是标准的SQL。 (自动id号和触发器的语法从dbms到dbms的变化很大。)

表“派对”是超类型。 表“inds”(个人)和“orgs”(组织)是子类型。 每一方必须一个个人或组织; 即使是错误的,一方也不可能两者兼而有之。 (这非常重要。)

-- The "supertype". Attributes that apply to both individuals and to 
-- organizations go in this table.
--
create table parties (
    party_id serial primary key,
    party_type char(1) check (party_type in ('I', 'O')),
    party_full_name varchar(45) not null,

    -- This unique constraint lets foreign keys reference this pair
    -- of columns.
    unique (party_id, party_type)
);

-- For organizations, a "subtype" of parties. There's nothing special about
-- the column "ein". It's just an attribute that applies to organizations,
-- but doesn't apply to individuals.
--
create table orgs (
    party_id integer primary key,
    party_type CHAR(1) not null default 'O' check (party_type = 'O'),
    ein CHAR(10), -- In the USA, federal Employer Identification Number

    -- This reference to a pair of columns, together with the CHECK
    -- constraint above, guarantees that a row in this table will 
    -- reference an organization in "parties". It's impossible for 
    -- a row in this table to reference an individual.
    --
    foreign key (party_id, party_type) 
        references parties (party_id, party_type) on delete cascade
);

-- For individuals, a "subtype" of parties. There's nothing special about
-- the column "height_in" (height in inches). It's just an attribute that 
-- applies to individuals, but doesn't apply to organizations.
--
create table inds (
    party_id integer primary key,
    party_type char(1) not null default 'I' check (party_type = 'I'),
    height_in integer not null check (height_in between 24 and 108),

    -- See comments in "orgs" above.
    foreign key (party_id, party_type) 
        references parties (party_id, party_type) on delete cascade
);

客户端代码使用可更新视图,而不是基表。 平台对可更新视图的支持各不相同。 大多数允许在视图上触发,这是我在下面使用的。

我为下面的人写了一个视图。 触发器仅处理插入。 更新和删除代码非常相似。 查看和支持组织的代码也类似。

create view people as
select t1.party_id, t1.party_full_name, t2.height_in
from parties t1
inner join inds t2 on (t1.party_id = t2.party_id);

create or replace function insert_into_people() 
returns trigger as
$$
begin
    insert into parties (party_full_name, party_type)
    values (new.party_full_name, 'I');
    insert into inds (party_id, height_in) values (currval('parties_party_id_seq'), new.height_in);
    return null;
end;
$$
language plpgsql;

create trigger insert_people
instead of insert on people
for each row
execute procedure insert_into_people();

在生产中,您可能几乎从所有用户撤消对基表的权限,并且只允许通过视图进行访问。 (你可能需要更多的观点。)

由于个人和组织都可以参加会议,因此您的会议参与者表将引用“派对”。“party_id”。

关于Desiging Database Patterns的一些消息来源

您可以在Database Answers Data Models链接中看到许多示例模式。

NIAM方法导致了ORM2和FCO-IM。 有关FCO-IM免费在线图书 这些方法理解关系表具有关于应用程序的关联的parmeterized语句,并保存其元组从中生成关于应用程序的真实语句的行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM