我有免费的付费主题桌。免费主题有下载链接支付主题有购买链接和价格。
下面是一个图形格式的数据库模式:

一个主题不可能既付费又免费。如何防止两个表(FreeThemes、PaidThemes)同时拥有主题的数据?
发布于 2022-01-05 17:45:43
这是Class table inheritance.的一个例子--这是一个非常有效的设计选择(我不认为这是“过于规范化”)--这是一种绕过关系模型的局限性之一的方法。
另一个限制是,不存在以声明方式声明您需要的业务规则的干净的、原生的方式。
有几种常见的方法可以解决这个问题。
第一种方法是将责任委托给应用层。如果有一个应用程序/服务连接到数据库,这并不可怕--特别是如果您可以将逻辑封装在单元测试中等等。
第二种方法是将逻辑嵌入触发器中。这允许您保证这一业务规则,即使许多应用程序使用数据库,但当业务逻辑发生变化时(例如,如果需要添加一个新的子类),则必须更改触发器。
最后一种选择是向Themes表中添加一个“类型指示符”,并使用该标志,而不是在子类表中存在一行,以确定主题是免费的还是付费的。同样,也不是超级优雅,并且要求客户端应用程序遵守该标志,但它确实巧妙地表达了业务意图。
发布于 2022-01-05 17:19:05
一个关于亚型的词。实现子类型约束的正确方法是使用断言(CREATE ASSERTION),但在主要DB中仍然不可用。我正在使用FKs,作为所有其他替代方法,它并不完美。人们争论了很多,所以和SE,什么是更好的。我也鼓励你检查其他方法。
-- Theme THM, of theme-type THM_TYP exists.
--
theme {THM, THM_TYP, -- other_common_attributes}
PK {THM}
SK {THM, THM_TYP}
CHECK THM_TYP in ('F', 'P')-- Free theme THM (of theme-type 'F') exists.
--
free_theme {THM, THM_TYP,
-- other attributes specific to free}
PK {THM}
FK {THM, THM_TYP} REFERENCES theme {THM, THM_TYP}
CHECK (THM_TYP = 'F')-- Paid theme THM (of theme-type 'P') exists.
--
paid_theme {THM, THM_TYP,
-- other attributes specific to paid}
PK {THM}
FK {THM, THM_TYP} REFERENCES theme {THM, THM_TYP}
CHECK (THM_TYP = 'P')注意:
All attributes (columns) NOT NULL
PK = Primary Key
AK = Alternate Key (Unique)
SK = Proper Superkey (Unique)
FK = Foreign Key遵循正式的规范化规则不会使您得到这个解决方案。free_theme表和paid_theme表都有FD {} --> {THM_TYP};换句话说,属性THM_TYP不依赖于PK {THM},因此这些表不在2NF中。
在这种情况下,FK和CHECK约束防止异常和逻辑错误--这首先是规范化的目标。
如果您对表不在2NF中有问题,下面是一种思考的方法:
为了解决这个问题,attribute.
THM_TYP
THM_TYP,并了解到问题的根本原因是当前SQL implementations.中缺少所需的交叉表约束(断言)。
发布于 2022-01-10 02:18:34
吻一下。一张两人的桌子--让价格是0.00表示免费。
(或者NULL可以表示“免费”,但我看不出有什么优势。)
https://stackoverflow.com/questions/70593875
复制相似问题