【问题标题】:Is there a more efficient way to store containers of objects in Access?有没有更有效的方法在 Access 中存储对象容器?
【发布时间】:2019-05-10 21:18:58
【问题描述】:

我正在尝试在 Access 2016 中创建一个关系数据库,以保留我们办公室中存储的物品的清单。它们中的大多数都装在某种盒子里,所以我决定每条记录都应该是一个Container,它可以是一个盒子、袋子或容纳多个物品的物理容器,也可以只是一个未包含的物品.例如,放在架子上的打印机仍将被视为Container,但容器的类型将为“无”。而一个装满小玩意的盒子的类型是“盒子”,并且它们的每个项目都将在单独的表中枚举。

每个Container 内可以有多个Item - 例如一个盒子可能包含一包笔、一根 HDMI 电缆和一个名片夹。所有三个项目在Item 表中都有自己的记录,其中包含描述项目的各种属性(品牌、颜色、数量,如果有多个相同的项目等)。每个Item 都通过以下方式链接到它的Container ContainerID - 关系是一对多的。

我设想这种设计的问题是数据冗余 - 因为容器既可以是文字容器,也可以只是一个项目(例如打印机),在后一种情况下,我必须将父级命名为 Container“打印机” ,并将孩子命名为Item“打印机”。或者我可以将Item 的名称字段留空,以便只命名Container,但我不确定这是否被认为是数据库设计中的不良做法。

另一个问题是我的设计不能很好地容纳子容器 - 例如如果在一个更大的盒子里有一个袋子,里面还有其他东西,我只需要提供一个描述性的标题“包含笔,电缆的袋子......”我无法想象有任何方法可以让我的数据库递归所以我想不出任何解决方案。考虑到我正在使用的盒子的大小,我会经常遇到这种情况。

所以我的问题有两个:

1) 对于我正在尝试实施的解决方案,是否有一种解决方法可以让我将容器整齐地存储在容器中?

2) 对于我想要完成的工作,是否有更有效的数据库设计?

【问题讨论】:

  • 我已经编辑了这个问题,试图让它不那么“过于宽泛”,我希望能提出进一步改进的建议,而不是进一步接近投票。
  • “递归”是定义/算法/表示的属性,而不是函数/关系的属性。 What are the options for storing hierarchical data in a relational database?How to create a MySQL hierarchical recursive query
  • “这个设计”到底是什么? PS 显而易见的设计,显然是您的设计,是“容器项目 [c] 包含项目 [i]”、“项目 [i] 具有描述 [d]”、“项目 [i] 具有属性 [p]”。关于“我的设计不能很好地容纳子容器”你为什么这么认为?您已经说过“每个项目都通过 ContainerID 链接到其容器”和“一个容器既可以是文字容器,也可以只是一个项目”。所以你的设计确实“巧妙地容纳了子容器”。
  • 关于“好”和“我不确定这是否被认为是数据库设计中的不良做法”:我们如何回答?我们必须改写教科书。是时候阅读已出版的关于信息建模和数据库设计的学术教科书了。 (记录和使用设计的语言和工具手册不是信息建模和数据库设计的教科书。)PS“数据冗余”(如“高效”和“好”和“坏”)并不意味着任何特别的东西&无论如何,只有“坏”“数据冗余”不是“好”。

标签: ms-access database-design ms-access-2016


【解决方案1】:

您的问题确实满足了许多可用的近距离投票选项,并且也可能吸引主要基于意见的答案,因为我确信有很多方法可以解决这个问题......但是,一种可能的“递归”解决方案可能如下:

创建一个Items 表,其中每条记录都包含一个唯一标识符ItemID 作为主键,以及项目的各种属性(例如描述、大小、颜色、值、类型等),还包括一个称为ContainerID 或Container 的外键字段可以填充Items 表本身中另一个项目的ItemID:

这样:

  • 您的打印机示例不再是一个容器,而只是一个具有适当属性且没有多余的多余记录的项目。
  • 许多项目可以共享相同的ContainerID 字段值,表示构成您的“bric-a-brac”的项目包含在同一个框中。
  • 由于ContainerID 指的是Items 表中的另一个项目,容器也可能具有ContainerID 值,允许您表示无限级别的嵌套容器:

这个问题与表示管理层次结构(或者实际上是任何层次结构)的问题非常相似,正如this question 中所探讨和回答的那样。

【讨论】:

  • 这真是个好主意,谢谢!尽管我想我理解这个理论,但我对如何实现这一点有点困惑 - 你是否建议每个 Item 都有一个 ContainerIDFK 和一个 ContainerID 属性,其中第一个是指另一个项目的ContainerID,所以项目本质上是相互链接的?
  • 不完全-我是说Items 表中的每条记录都有一个唯一的ItemID PK,并且Container 字段将包含ItemID 中的另一个项目桌子。类似于我的答案中链接的问题中描述的设置。
  • 啊,我明白了,所以对于一个包含一个包含小部件的包的框,该框在Container 表中有一个条目,该包在Item 表中有一个带有@ 的条目盒子的 987654346@,小部件在 Item 表中有一个条目,包的 ContainerID。
  • 我想你已经明白了,但只有Items 表,没有Container 表 - 我在我的答案中添加了一个示例来帮助解释。当然,这只是解决这个问题的一种方法。
  • @Lou,是的:您可以在查询中使用自联接 - 链接的答案仅使用 VBA 构造具有足够自联接的 SQL 查询以遍历层次结构的所有级别。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-07
  • 1970-01-01
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
相关资源
最近更新 更多