希望有人可以通过一个例子,或者某些建议的阅读来解释这个问题。 我想知道在类层次结构等效之后建模表的最佳设计方法是什么。这可以通过一个例子来描述:
abstract class Card{
private $_name = '';
private $_text = '';
}
class MtgCard extends Card{
private $_manaCost = '';
private $_power = 0;
private $_toughness = 0;
private $_loyalty = 0;
}
class PokemonCard extends Card{
private $_energyType = '';
private $_hp = 0;
private $_retreatCost = 0;
}
现在,在对表格进行建模以与此类层次结构同步时,我已经找到了非常相似的东西:
TABLE Card
id INT, AUTO_INCREMENT, PK
name VARCHAR(255)
text TEXT
TABLE MtgCard
id INT, AUTO_INCREMENT, PK
card_id INT, FK(card.id)
manacost VARCHAR(32)
power INT
toughness INT
loyalty INT
TABLE PokemonCard
id INT, AUTO_INCREMENT, PK
card_id INT, FK(card.id)
hp INT
energytype ENUM(...)
retreatcost INT
我遇到的问题是试图弄清楚如何将每个Card
记录与包含相应表格中的详细信息的记录相关联。具体来说,如何确定我应该查看哪个表。
我应该向VARCHAR
添加Card
列以保存关联表的名称吗?这是我和我的同事唯一解决的问题,但它似乎太“脏”了。 保持设计可扩展性是关键,允许轻松添加新的子类。
如果有人可以提供一个示例或资源来显示一种干净的镜像类/表层次结构的方式,那么我们将非常感激。
答案 0 :(得分:5)
Google“泛化专业化关系建模”。您将找到几篇关于如何使用关系表对gen-spec模式建模的优秀文章。在SO中已经多次询问过同样的问题,细节略有不同。
这些文章中最好的将确认您决定为一般数据设置一个表,为特殊数据设置单独的表。最大的区别将是他们推荐使用主键和外键的方式。基本上,他们建议专门的表有一个单一的列,可以执行双重任务。它作为专用表的主键,但它也是一个重复广义表的PK的外键。
维护起来有点复杂,但在加入时非常甜蜜。
还要记住,在将新类添加到层次结构时需要DDL。
答案 1 :(得分:3)
基本上没有。
忘记类层次结构,存储模型以及特定于您的应用和特定应用语言的任何内容。除非您想将RDb用作文件的存储位置,否则为从属服务器。
如果您想要关系数据库的强大功能和灵活性(特别是可扩展性),那么您需要独立于任何应用程序对其进行建模,并使用RDb原则,而不是应用程序语言要求。将您的应用程序上下文搁置一段时间,并将数据库设计为数据库。了解他们。规范化(消除所有重复)。了解结构和规则,并实施它们。当您这样做时,您的查询和“映射”将毫不费力。没有“阻抗”。使用正确的数据类型,不会出现不匹配。
您需要的结构是普通的子类型超类型。这些是关系数据库术语,已在RM中存在超过30年,在关系数据库产品中已存在超过23年。无需称他们为有趣的新名字。除了癌症肿瘤外,Wiki不是学术参考。
鉴于您的表格作为起点非常正确(您已自动规范化),您需要:
将Card.Id重命名为Card.CardId
删除子类型的ID,它们是100%冗余的; CardId既是PK也是FK。
添加鉴别器Card.CardType CHAR(1)或TINYINT。当CardType未知时,这将标识要加入的子类型。
看来你并没有完全理解外键的概念,所以最好先加油。它在这里以简单,普通的形式实现:
ALTER TABLE MtgCard
ADD CONSTRAINT Card_MtgCard_fk
FOREIGN KEY (CardId)
REFERENCES Card(CardId)
Card与MtgCard或PokemonCard之间的关系始终为1 :: 1。只有当卡加{MtgCard |时,超类才能完成PokemonCard}具有相同的CardId。在您的情况下,只能有一个子类型,易于使用简单的CHECK约束强制执行。
在other cases中,多个子类型非常合法。
人是教师或人是学生
在关系数据库中,没有加入“从”或“到”(或上/下或左/右)的概念,这些概念只是为了帮助我们人类;你可以从你拥有的任何桌子/钥匙开始,然后去你需要的任何桌子。仅在没有关系标识符的情况下才需要中间的表(即,其中附加的代理,ID列用作PK 而不是有意义的自然键)。< / p>
Quick Reference到标准关系数据库图。