好的,我正在为“Box Items”制作一张桌子。

现在,一个Box Item,取决于它用于什么/项目的状态,可能最终与“Shipping”相关联。框或“返回”框框。

Box Item可能有缺陷:如果是,则在Box Item的行(IsDefective)中设置一个标志,Box Item将被置于“返回”状态。框(其他项目将返回给该供应商)。否则,Box Item最终将被放入“Shipping”中。包装盒(包含其他物品)。 (请注意,Shipping和Returns框有自己的表:所有框都没有一个公共表格......虽然如果可能的话,我应该考虑这样做,作为第三种可能性?)

也许我今天没有想清楚,但我开始质疑在这种情况下应该做些什么。

我的直觉告诉我,对于每个可能的关系,我应该有一个单独的字段,即使在任何给定时间只能发生其中一个关系,这会使Box Items的架构看起来像:

BoxItemID 描述 IsDefective ShippingBoxID ReturnBoxID 等...

这会使关系变得清晰,但似乎很浪费(因为任何时候只会使用其中一种关系)。那么我想我可以只为BoxID创建一个字段,并根据IsDefective字段确定它所引用的BoxID(一个Shipping或一个返回Box ID):

BoxItemID 描述 IsDefective BoxID 等...

这似乎不那么浪费,但并不适合我。这种关系并不明显。

所以,我把它给你,Stackoverflow的数据库大师。在这种情况下你会做什么?

编辑:谢谢大家的意见!给了我很多思考的东西。首先,我将在下次启动这样的项目时使用ORM。 =)对于两个,因为我现在不对,我会咬四个字节并使用两个字段。

再次感谢大家!

有帮助吗?

解决方案

我患有精神病毒和哑膜。

走多态路径(必须根据另一个字段的内容找出你的外键指向哪个表)将是一个痛苦。编写那些约束可能很难(我不确定大多数数据库会支持本机,我认为你必须使用触发器)。

物品是否会在桌子之间移动?坚持使用两个具有相同定义的表,其中一个用于返回,一个用于运输可能是最简单的路径。如果你想坚持你最初提出的定义(使用两个单独的字段)是完全合理的。

“过早优化是所有邪恶的根源”所有这一切。虽然看起来很浪费,但请记住你要存放的东西。由于它们是ID,它们可能只是整数,可能是4个字节。每条记录浪费四个字节基本上没什么。实际上,由于填充物以便将物品放在偶数地址或其他类似物上,因此它可以是“自由的”。把那个额外的字段放在那里。这完全取决于数据库设计。

除非你有充分的理由去采用多态路径(就像你在一个内存很少的嵌入式系统上,或者你必须在一些非常慢的9600bps链路上复制),否则你可能不值得头疼。以结束。必须将所有这些特殊情况写入您的查询可能会很烦人。

快速示例:在两个表之间进行连接,如果要连接,则基于是否设置了isDefective标志会很麻烦。仅仅使用两列中的一列可能足以让你节省下来的麻烦,至少对我而言。

其他提示

我会考虑为盒子制作一个表格,而盒子类型是盒子表格的一列。这将简化关系并使查询框类型变得容易。所以盒子项只有一个外键到boxId。

我会使用Hibernate所谓的表 - 每个子类,所以我的数据库最终会有3个表格用于Boxes: Box ShippingBox ReturnBox BoxItem 中的FK将指向 Box

你所谈论的是多态关系。可以引用多个其他表的单个ID。有几个框架支持这一点,但是,它(可能)不利于数据库完整性(可能是一个完整的其他讨论,无论您的数据库或您的应用程序是否应保持参照完整性)。

这个怎么样?

BoxItem:
BoxItemID, Description, IsDefective

Box:
BoxID, Description

BoxItemMap:
BoxID, BoxItemID, BoxItemType

然后你可以将BoxItemType作为枚举,或者在你的应用程序中将常量定义为“返回”的整数。或“运输”作为盒子的类型。

同意上面的多态性讨论,虽然它有可能被用得很差,但它仍然是一个可行的解决方案。

基本上你有一个名为box的基表。然后你有另外两个表,包装箱和退货箱。这两个添加任何特殊的额外字段。它们与1:1 fk.Boz基表的框相关,具有所有框类型的公共字段。

您将BoxItem与框表相关联。获得正确的框类型的方法是通过执行查询,根据键将子框与根框连接。基本框和子框中的记录都属于该类型。

你必须要小心提到,当你创建一个正确完成的盒子类型时。这就是测试的目的。添加它们的代码只需要写一次。或使用ORM。

几乎所有ORM都支持这一策略。

我只使用一个包含IsDefective,ShippingBoxID,发货箱相关字段,ReturnBoxID和返回框相关字段的BoxItems表。每条记录的某些字段始终为NULL。

这是一个非常简单和不言而喻的设计,下一个开发人员不太可能会被混淆。从理论上讲,这种设计效率很低,因为每行都有保证的空场。实际上,无论如何,数据库往往具有每行所需的最小存储大小,因此(除非字段数量很大),这种设计尽可能高效,并且更容易编码。

我可能会选择:

BoxTable:
box_id, box_descrip, box_status_id ...
     1, Lovely Box, 1
     2, Borked box, 2
     3, Ugly Box, 3
     4, Flammable Box, 4

       BoxStatus:
       box_status_id, box_status_name, box_type_id, ....
                   1,Shippable, 1
                   2,Return, 2
                   3,Ugly, 2
                   4,Dangerous,3

                BoxType:
                box_type_id, box_type_name, ...
                          1, Shipping box, ...
                          2, Return box, ....
                          3, Hazmat box, ...

通过这种方式,Box Status定义了框类型,如果您需要稍后扩展到更多状态级别或框类型,它将非常灵活。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top