Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用继承设计数据库是个好主意吗?_Sql_Database_Inheritance_Database Design - Fatal编程技术网

Sql 使用继承设计数据库是个好主意吗?

Sql 使用继承设计数据库是个好主意吗?,sql,database,inheritance,database-design,Sql,Database,Inheritance,Database Design,例如,我有两个表:“customer”和“staff”。它们几乎相同,只有两个属性不同。那么,我是否应该创建另一个名为“person”的表,该表包含“customer”和“staff”的所有相同属性,然后创建指向该“person”的fk键?类似于类设计中的继承 这种方法有什么缺点吗?我说它的设计很好,因为你没有重复数据,这就是数据规范化的原因 只有一件事是,只要你规范化你的加入数量就会增加。是的,这种方法有一个缺点。联接增加了查询的复杂性(在某些情况下非常复杂),如果不小心的话,可能会增加查询时

例如,我有两个表:“customer”和“staff”。它们几乎相同,只有两个属性不同。那么,我是否应该创建另一个名为“person”的表,该表包含“customer”和“staff”的所有相同属性,然后创建指向该“person”的fk键?类似于类设计中的继承


这种方法有什么缺点吗?

我说它的设计很好,因为你没有重复数据,这就是数据规范化的原因


只有一件事是,只要你规范化你的加入数量就会增加。

是的,这种方法有一个缺点。联接增加了查询的复杂性(在某些情况下非常复杂),如果不小心的话,可能会增加查询时间

相反,实现这一点的标准方法(即,当子类之间只有几个属性不同时,模拟对象继承)是执行以下操作:。此方法以牺牲少量未使用的数据库空间为代价来防止数据库连接

它的工作原理是这样的:创建一个包含所有属性的表,包括仅应用于其中一个属性的属性,以及一个
type
属性来指定对象类型。例如,如果
customer
具有以下属性:

id
name
email
password
order\u date

staff
具有以下属性:

id
name
email
password
hire\u date

然后创建一个表,其中包含所有属性的列和类型:

id
类型
姓名
电子邮件
密码
订单日期
雇佣日期


类型
列将始终包含“客户”或“员工”。如果
type
为“customer”,则
hire\u date
始终为空,没有意义。如果
type
为“staff”,则
order\u date
始终为空,并且没有意义。

您正在描述一个模式调用。这是一个有效的设计,但和其他设计一样,它必须以良好的判断力使用。阅读Martin Fowler的“企业应用程序架构模式”,了解其优缺点的更多细节


有些人警告不要使用联接,但只有在需要子类特定列时才需要联接。当给定的查询只需要公共列时,可以避免额外的联接。

Pranay Rana和Ben Lee都是正确的,最终的答案是:“这取决于”

您必须权衡子类特定列的数量与常用列的数量,以确定适合您的内容。单表继承不能很好地扩展:当您必须引入第三种类型的子类(如供应商)时会发生什么

因此,您将如何对待同时也是客户的员工?

查阅“泛化-专业化-关系建模”。你会找到一些关于这个主题的好文章。大多数示例都遵循与Bill提供的类表继承链接相同的模式

还有一个小细节。专用表(适用于您的客户和员工)不会自动编号其id fieid。相反,当您填充它们时,id字段应该在通用表中获得id字段的副本(在您的案例中是person)

这使得专用ID具有双重功能。它们都是对genralized表中对应行的pk和fk引用。这使得连接更容易、更快


创建视图时,可以方便地将每个专用表与通用表连接起来。或者,您可以创建一个大视图,该视图生成的数据与您在另一个响应建议的单个表继承模式中看到的数据相同。它基本上是一组连接的并集

我不同意这种评估。是的,您没有重复数据,但正如您自己指出的,您正在增殖
连接。如果只有几个属性不同,
单表继承
是一个更好的解决方案,因为它避免了
连接
,同时也不会重复任何数据。@Ben Lee-这取决于您如何查看它以及数据有多大,但我肯定支持OP design,你的设计建议也是很好的,但这取决于我们的情况…谢谢你是对的,这取决于具体情况。但假设只有几个独特的行,我认为STI更好。我承认这可能是我自己的偏好偏见泄露到了分析中。单表继承的一个可能缺点是:在提议的示例中,如果其中一名员工从公司购买东西,他将成为客户。。。假设在大表继承中有一个“type”字段,那么使用哪种类型?工作人员顾客员工客户?当一个实体完全不存在属于多个“类别”的风险时,BTI最有效。否则,你会开始在所有地方放置标志,像select*from BigTable,其中type=“STAFF”会变得很麻烦……谢谢,如果我有其他表也有id、名称、电子邮件、密码,但有一些不同的特定属性,怎么样?@Sun,然后将这些特定属性添加到大列表中。例如,如果您有一个
管理员
类型,其中包含id、姓名、电子邮件、密码和唯一字段
权限
,则您的单个表将包含id、类型、姓名、电子邮件、密码、订单日期、雇用日期、权限。现在类型可以是“客户”、“员工”或“管理员”。不适用于特定类型的字段只保留为空。有道理吗?我明白了。但是,您认为如果有许多表这样连接到一个表中,那么一行中会有很多字段保持为空吗?@Sun,这是您必须根据代码做出的决定。空行非常便宜。但左连接也是如此。你必须决定是否加入