Database design 多重关系是否是不良设计的证据?

Database design 多重关系是否是不良设计的证据?,database-design,Database Design,大家好 我一直在学习数据库和数据库设计,但我发现我仍然遇到一个自己无法回答的问题。因此,我向社区提出这个问题,希望有比我更有知识/经验的人能够回答 我的任务是建立一个数据库,跟踪船队的库存水平 当前设计为每艘船提供了一个表格,其中列出了所有可能的零件(机械类型、零件号、品牌、序列号等) 这意味着一台机器或零件的细节可以被复制很多次(实际上有多少次船) 我一直在根据自己学到的知识进行重新设计,我将按照以下思路提出设计方案: [SHIP] ID, Name, Class, Tonnage, Flee

大家好

我一直在学习数据库和数据库设计,但我发现我仍然遇到一个自己无法回答的问题。因此,我向社区提出这个问题,希望有比我更有知识/经验的人能够回答

我的任务是建立一个数据库,跟踪船队的库存水平

当前设计为每艘船提供了一个表格,其中列出了所有可能的零件(机械类型、零件号、品牌、序列号等)

这意味着一台机器或零件的细节可以被复制很多次(实际上有多少次船)

我一直在根据自己学到的知识进行重新设计,我将按照以下思路提出设计方案:

[SHIP]
ID, Name, Class, Tonnage, Fleet, Superintendent etc.

[Machinery]
ID, Type, Make, Model etc. (Can have separate table for manufacturers and types if required)

[Part]
ID, Part number, Description, etc.
以上是三个主要表格,现在开始变得困难了

每艘船可以有多个机械项目,每个机械项目可以出现在多艘船上(需要一个连接表)

每个机械项目可以有多个零件,每个零件可以属于多个机械项目(另一个连接表)

可能会有成百上千的部件,这将使连接表变得巨大

此外,只要您想跟踪库存,您就可以查看另一个连接表

[Stock Level]
ShipID, PartID, Stock Level
此外,如果您想要最低库存(可以与库存水平相结合?)

最后,如果您希望有标准化的数据库(即无零件号1、零件号2或序列号1、序列号2)

你需要多放几张桌子

[Serial Numbers]
ShipID, MachineryID, Serial No

[Part Numbers]
PartID, Part Number
序列号可能是相当标准的,没有问题,但是[零件号]至少需要与[零件]表中相同数量的记录

地图(尽我所能在没有图片的情况下表现出来,为了简单起见省略了交叉点)

V代表许多
-|代表一
-----<序列号
|五
|             |
船舶>-<机械>-<零件---<零件号
V V
|                          |
------库存水平-------
现在真正的问题是,我是否在基本设计原则中遗漏了一些可以消除如此巨大的连接表的东西,或者这是这种数据库所期望的

同样,在零件号这样的情况下,规范化需要一个至少具有相同记录数的附加表,而不是原始表中的额外列,这是您稍后要进行反规范化以提高查询速度的事情吗

任何关于外部资源(包括其他论坛、教程、书籍)的提示、提示或指针都将不胜感激

欢迎所有答案,提前感谢您提供的任何帮助


Dave

首先,:多对多关系并不是糟糕设计的指标

其次,联接表总是比它们所连接的表大。如果有两个表,每个表有100条记录,则联接表最多可以有10000条记录

但是联接表只不过是整数对,当您为它们编制索引时,它们的速度会非常快

编辑以添加:

你评论道:

我认为索引是由数据库管理系统完成的

由您来告诉DBMS索引什么。之后,将自动使索引保持最新

有些数据库管理系统有一些工具,可以监视您的系统运行情况,并就哪些索引是有益的向您提供建议

您的设计过程很好,因此您可能走上了正确的轨道。

除此之外,如果您的DBMS支持,连接表通常是很好的候选对象

例如,对

[Stock Level]
ShipID, PartID, Stock Level
…将使用相同的
ShipID
将行存储在一起,这样可以非常有效地获取与给定船舶关联的所有行

另一方面,群集

[Stock Level]
PartID, ShipID, Stock Level
…将具有相同的
PartID
的行存储在一起,这样可以有效地获取与给定零件关联的行

如果需要在这两个方向上进行查询,则需要两个索引(
{ShipID,PartID}
{PartID,ShipID}
)。通常,聚集表中的二级索引必须包含,这使得使用多个索引聚集表的成本很高。然而,在本例中,我们无论如何都会覆盖相同的字段(只是顺序不同),因此二级索引中没有开销。您甚至可以考虑使用第二索引来考虑<代码>股票级别< /代码>,以避免双重查找(聚类索引已经自然地覆盖它)。 在您的DBMS不支持集群的情况下,考虑索引<代码> {Studio、PartID、SturyList} /Cube >(或<代码> {PARDD、ShipID、SturyList} /代码>或两者)。这样,您的查询就被索引覆盖了,不需要访问表堆。从本质上讲,除了在(冗余)表堆上浪费额外的空间外,您可以实现集群的效果



除此之外,一些DBMS支持前沿,大大减少了连接表索引中重复值的存储空间。压缩聚集表(其本身是索引)以获得最大效果。

大型连接表是正常的。如果你说的“大”是指几百万行,那不是很大,而且很容易索引。快速回答你们,这回答了我的一个问题。不过我需要做一些索引方面的研究。我有点认为索引是由DBMS自动完成的,但我会做一些调查,因为这可能对速度有很大帮助。我认为我最初的设计(再加上一点规范化)或多或少是正确的方法。在我的“相对较小”的数据库中,索引连接表的执行速度足够快。我曾经玩过索引,看起来了解更多的东西会很好
[Stock Level]
ShipID, PartID, Stock Level
[Stock Level]
PartID, ShipID, Stock Level