Database design 塑造自然客户和合法客户的最佳方式
我想设计我的项目的数据模型,但我在“客户”部分有一个问题,因为我有两种类型的客户:自然人和法律实体 哪种方式最好: 方法1: 要有3个这样的表:Database design 塑造自然客户和合法客户的最佳方式,database-design,class-table-inheritance,single-table-inheritance,Database Design,Class Table Inheritance,Single Table Inheritance,我想设计我的项目的数据模型,但我在“客户”部分有一个问题,因为我有两种类型的客户:自然人和法律实体 哪种方式最好: 方法1: 要有3个这样的表: Customers: ID int not null (PK) CustomerType bit not null NaturalPersonID int (FK) LegalPersonID int (FK) NaturalPeople: ID int not null (PK) Fi
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显示客户类型(自然或合法)
方法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字段和FirstName字段中的RegistrationCode为空
方法4:
我没有想到的任何其他方式,你可以建议
另外,我正在MS SQL Server 2012中实现我的数据库任何一种方法都有其优点和缺点,根据您的应用程序需求和分析,它们中的任何一种都是适用的
顺便说一句,我更愿意使用方法1,但要考虑一些因素:
Customer
表将是NaturalPeople
和
LegalEntities
,客户的主键将是主键
另外两个人中的一个其他两个的共享信息,如客户编号、客户类型
搜索客户全名(标准名称)等关键字段,以便您可以对其设置索引
几句话:不要忘记自然人和法律实体之间存在着潜在的关系,自然人属于或代表法律实体。我会毫不犹豫地在NaturalPeople表中添加LegalEntityID FK
而且,为了简单起见,当外键字段指向“NaturalPeople”表时,我不会将其命名为“NaturalPersonID”。称之为自然人,会让事情变得更清楚。“LegalPersonID”字段也是如此。您甚至可以将对象/表的命名限制为“人”和“实体”,或“人”和“机构”(这是为了避免关系数据库中实体对象/表和实体概念之间的混淆).在这种情况下,我通常做一个表
Customer
,它有一个PK和一个鉴别器列CustomerType
,还有两个细节表,一个用于自然,一个用于法律,但这些附加表的主键与Customers
表的PK相同(与方法1类似,但两个子类型表没有单独的键)。这样查询更简单,您可以在主控和详细信息之间强制执行1:0约束,没有代理键,数据也被规范化。方法1是一种称为
方法2是一种设计模式,称为
您可以通过访问标签并打开“信息”选项卡来了解这些信息
方法3有一个名字,我现在想不起来
在你的情况下,我会选择方法1
方法1中,你已经很仔细地遵循了这个模式。我建议你考虑的是共享主键。类表继承和共享主键工作在一起。
查看党的数据模型:你如何评价“最佳”??如果一个实体既可以是合法性也可以是自然人?也就是说,一个实体可以从合法性或自然人中衍生出来,考虑到我使用的是方法1create 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')
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')