6

我想设计我的项目的数据模型,但我在“客户”部分遇到问题,因为我有两种类型的客户:自然人和法人实体这是最好的方法:

方法1:有3个这样的表:

    Customers:
    ID int not null (PK)
    CustomerType bit not null
    NaturalPersonID int (FK)
    LegalPersonID int (FK)

    NaturalPeople:
    ID int not null (PK)
    FirstName nvarchar(50) not null
    LastName nvarchar(50) not null
    NationalSecurityNumber char(10) not null
    ...

    LegalEntities:
    ID int not null (PK)
    CompanyName nvarchar(100) not null
    RegistrationNumber char(20) not null
    ...

NaturalPersonID 或 LegalPersonID 中的一个已填写,另一个为 null 且 CustomerType 显示客户类型(Natural 或 Legal)

方法 2:拥有一个包含所有字段的表:

    ID int not null (PK)
    CustomerType bit not null
    FirstName nvarchar(50)
    LastName nvarchar(50)
    NationalSecurityNumber char(10)
    CompanyName nvarchar(100)
    RegistrationNumber char(20)
    ...

对于每个客户,某些字段已填写,其他字段为空

方法 3:拥有一个包含一些字段的表:

    ID int not null (PK)
    CustomerType bit not null
    FirstName nvarchar(50)
    LastName nvarchar(100)
    NationalSecurityNumber varchar(20)
    ...

自然地为自然客户填充了这些字段。但如果客户是合法客户,我们会按逻辑放置数据。例如,LastName 字段中的 CompanyName 和 NationalSecurityNumber 字段中的 RegistrationCode 并且 FirstName 字段为空。

方法4:我没有想到的任何其他方式,你可以建议

PS 我在 MS SQL Server 2012 中实现我的数据库

4

5 回答 5

7

任何一种方法都有优点和缺点,它们中的任何一种都将根据您的应用程序要求和分析而适用。
顺便说一句,我更喜欢使用Method 1一些考虑因素:

  1. Customertable 将是 和 的基表NaturalPeopleLegalEntitiesCustomer 的主键将是另外两个的主键。
  2. 客户表将包含:
    其他两个共享信息,如客户编号,客户类型...。
    搜索客户全名(标准名称)等关键字段,因此您可以对其设置索引
  3. 避免将一个字段用于两个不同的业务价值,例如:

    The fields are filled for the natural customers naturally. 
    But if the customer is a Legal one, we put data logically. For example 
    CompanyName in the LastName field and RegistrationCode in
    the NationalSecurityNumber field and the FirstName field is null.
    

    如果不分离字段,迟早你会受到影响,因为违反了第一范式(认为如果 National_Security_Number )是 NaturalPeople 的强制值,RegistrationCode 是 LegalEntities 的可选值。您不能在字段上设置唯一键或强制检查。

  4. 其他实体(如帐户、标志、地址...)将仅引用客户表。

  5. 您将需要对客户表实施简单搜索,并对合法和自然客户进行高级搜索。
于 2013-06-25T10:56:38.813 回答
1

在这种情况下,我通常会做一个Customer具有 PK 和鉴别器列的CustomerType表,以及两个详细表,一个用于 Natural,一个用于 Legal,但是这些附加表的主键与表的 PK 相同Customers(类似于您的方法一个,但没有两个子类型表的单独键)。这样查询就更简单了,你可以在 master 和 detail 之间强制执行 1:0 约束,没有代理键并且数据被规范化。

于 2013-06-25T11:45:10.810 回答
0
create table party_type (
  id serial primary key,
  description text not null unique
);

insert into party_type ('description') values
('Organization'),
('Individual'),
('Automated Agent');

create table party (
  id serial primary key,
  party_type_id int not null references party_type(id),
  organization_name text null,
  last_name text null,
  first_name text null,
);

insert into party (party_type_id, organization_name) values (1, 'Acme, Inc');
insert into party (party_type_id, last_name, first_name) values (2 'Doe', 'John');

create table role_type (
  id serial primary key,
  description text not null unique
);

insert into role_type ('description') values
('Customer'),

create table party_role (
  party_id int not null references party(id),
  role_type_id int not null references party_role_type(id),
  primary key (party_id, role_type_id)
);

/* add both parties as customers: */
insert into party_role values (1, 1);
insert into party_role values (2, 1);

create table identifier_type (
  id serial primary key,
  description text not null unique
);

insert into identifier_type ('description') values
('Social Security Number'),
('Registration Number');

create table party_identifier (
  party_id int not null references party(id),
  identifier_type_id int not null references identifier_type(id),
  id_number text not null,
  primary key (party_id, identifier_type_id)
);

insert into party_identifier values
(1, 2, 'some company reg number'),
(2, 1, 'some ssn')
于 2013-06-25T20:12:30.200 回答
0

几句话:不要忘记自然人和法人实体之间存在潜在的关系,自然人属于或代表法人实体。我会毫不犹豫地将 LegalEntityID FK 添加到 NaturalPeople 表中。

而且,为了简单起见,当它指向“NaturalPeople”表时,我不会将外键字段命名为“NaturalPersonID”。称它为 NaturalPeopleID,它会让事情变得更清晰。“LegalPersonID”字段也是如此。您甚至可以将对象/表的名称限制为“人”和“实体”,或“人”和“机构”(这是为了避免实体对象/表与关系数据库中的实体概念之间的任何混淆)。

于 2013-06-25T11:34:42.907 回答
0

方法 1 是一种称为的设计模式。

方法 2 是一种称为的设计模式。

您可以通过访问标签并打开信息选项卡来阅读这些内容。

方法 3 有一个名字,目前我不知道。

在你的情况下,我会选择方法1。

在方法 1 中,您已经非常接近地遵循了该模式。我建议您考虑的一件事是共享主键。类表继承和共享主键可以很好地协同工作。

于 2013-06-25T12:06:06.117 回答