Database design 塑造自然客户和合法客户的最佳方式

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

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

方法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显示客户类型(自然或合法)

方法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
    ,客户的主键将是主键 另外两个人中的一个
  • 客户表将包含:
    其他两个的共享信息,如客户编号、客户类型
    搜索客户全名(标准名称)等关键字段,以便您可以对其设置索引
  • 避免将字段用于两个不同的业务值,例如:

    如果你不把田地分开,很快或很晚你都会因为违规而受苦(想想吧 如果国家安全(U编号)是 NaturalPeople和RegistrationCode是的可选值 法律性。不能在字段上设置唯一键或强制检查

  • 其他实体(如账户、标志、地址等)将 仅引用客户表

  • 您将需要对Customer表和 对合法客户和自然客户的高级搜索

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


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

    在这种情况下,我通常做一个表
    Customer
    ,它有一个PK和一个鉴别器列
    CustomerType
    ,还有两个细节表,一个用于自然,一个用于法律,但这些附加表的主键与
    Customers
    表的PK相同(与方法1类似,但两个子类型表没有单独的键)。这样查询更简单,您可以在主控和详细信息之间强制执行1:0约束,没有代理键,数据也被规范化。

    方法1是一种称为

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

    您可以通过访问标签并打开“信息”选项卡来了解这些信息

    方法3有一个名字,我现在想不起来

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


    方法1中,你已经很仔细地遵循了这个模式。我建议你考虑的是共享主键。类表继承和共享主键工作在一起。

    查看党的数据模型:你如何评价“最佳”??如果一个实体既可以是合法性也可以是自然人?也就是说,一个实体可以从合法性或自然人中衍生出来,考虑到我使用的是方法1
    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')
    
    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')