mysql 表继承_如何在数据库中表示继承?

单表继承(也称为每层次结构表继承):

在第一个选项中使用单个表可能是最简单的设计。如您所述,许多属于子类型的NULL属性必须在不适用这些属性的行上赋予值。使用此模型,您将拥有一个策略表,它看起来像这样:

+------+---------------------+----------+----------------+------------------+

| id   | date_issued         | type     | vehicle_reg_no | property_address |

+------+---------------------+----------+----------------+------------------+

|    1 | 2010-08-20 12:00:00 | MOTOR    | 01-A-04004     | NULL             |

|    2 | 2010-08-20 13:00:00 | MOTOR    | 02-B-01010     | NULL             |

|    3 | 2010-08-20 14:00:00 | PROPERTY | NULL           | Oxford Street    |

|    4 | 2010-08-20 15:00:00 | MOTOR    | 03-C-02020     | NULL             |

+------+---------------------+----------+----------------+------------------+

\------ COMMON FIELDS -------/          \----- SUBTYPE SPECIFIC FIELDS -----/

保持设计简单是一个优点,但这种方法的主要问题如下:在添加新的子类型时,您必须更改表以适应描述这些新对象的属性。当您有许多子类型,或者您计划定期添加子类型时,这很快就会出现问题。

数据库将无法强制应用哪些属性,哪些属性不适用,因为没有元数据来定义哪些属性属于哪些子类型。

您也无法强制执行NOT NULL应该是必需的子类型的属性。您必须在应用程序中处理此问题,这通常不太理想。

具体表继承:

解决继承问题的另一种方法是为每个子类型创建一个新表,重复每个表中的所有公共属性。例如:

--// Table: policies_motor

+------+---------------------+----------------+

| id   | date_issued         | vehicle_reg_no |

+------+---------------------+----------------+

|    1 | 2010-08-20 12:00:00 | 01-A-04004     |

|    2 | 2010-08-20 13:00:00 | 02-B-01010     |

|    3 | 2010-08-20 15:00:00 | 03-C-02020     |

+------+---------------------+----------------+

--// Table: policies_property

+------+---------------------+------------------+

| id   | date_issued         | property_address |

+------+---------------------+------------------+

|    1 | 2010-08-20 14:00:00 | Oxford Street    |

+------+---------------------+------------------+

这种设计基本上解决了单表方法确定的问题:现在可以使用强制属性NOT NULL。

添加新子类型需要添加新表而不是向现有表添加列。

也没有为特定子类型设置不适当属性的风险,例如vehicle_reg_no属性策略的字段。

type单表方法中不需要属性。现在,类型由元数据定义:表名。

然而,这个模型也有一些缺点:公共属性与子类型特定属性混合在一起,并且没有简单的方法来识别它们。数据库也不会知道。

定义表时,必须重复每个子类型表的公共属性。那肯定不是干的。

搜索所有策略而不管子类型变得困难,并且需要一堆UNIONs。

无论类型如何,您都必须查询所有策略:SELECT     date_issued, other_common_fields, 'MOTOR' AS typeFROM       policies_motorUNION ALLSELECT

date_issued, other_common_fields, 'PROPERTY' AS typeFROM       policies_property;

请注意,添加新子类型将需要修改上述查询,并UNION ALL为每个子类型添加一个额外的查询。如果忘记此操作,这很容易导致应用程序中出现错误。

类表继承(又称每种类型的表继承):

这是@David在另一个答案中提到的解决方案。您为基类创建一个表,其中包含所有常用属性。然后,您将为每个子类型创建特定的表,其主键也充当基表的外键。例:CREATE TABLE policies (

policy_id          int,

date_issued        datetime,

-- // other common attributes ...);CREATE TABLE policy_motor (

policy_id         int,

vehicle_reg_no    varchar(20),

-- // other attributes specific to motor insurance ...

FOREIGN KEY (policy_id) REFERENCES policies (policy_id));CREATE TABLE policy_property (

policy_id         int,

property_address  varchar(20),

-- // other attributes specific to property insurance ...

FOREIGN KEY (policy_id) REFERENCES policies (policy_id));

该解决方案解决了其他两种设计中发现的问题:强制属性可以强制执行NOT NULL。

添加新子类型需要添加新表而不是向现有表添加列。

没有为特定子类型设置不适当属性的风险。

不需要type属性。

现在,公共属性不再与子类型特定属性混合。

我们终于可以保持干爽。创建表时,无需为每个子类型表重复公共属性。

管理id策略的自动递增变得更容易,因为这可以由基表处理,而不是每个子类表独立生成它们。

现在,无论子类型如何搜索所有策略都变得非常简单:不需要UNION- 只需要一个SELECT * FROM policies。

我认为类表方法在大多数情况下是最合适的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值