【问题标题】:Database table normalization (Many relations)数据库表规范化(许多关系)
【发布时间】:2013-01-29 21:23:30
【问题描述】:

我有以下表格:

商品 { item_id, item_name, item_price,......}
部门 { division_id, division_name, division_address,......}
仓库 { 仓库 ID、仓库名称、........}
仓库分区 { partition_id、分区名称、........}
WarehouseRacks { rack_id, rack_name,.......}

现在,为了跟踪项目的位置,我有下表(关系)。

itemLocation { item_id, division_id, warehouse_id, partition_id, rack_id, floor_number}

它准确地跟踪一个项目的位置,但为了获得一个项目的位置信息,我必须加入五个表,这可能会导致性能问题。

此外,如果我们不获取整个字段,则该表没有任何主键。这会引起任何问题吗?有没有更好的方法来做到这一点?

谢谢。

【问题讨论】:

  • 如果您能命名您正在使用的 DBMS,以及您的表的大致大小(以行为单位),将会有所帮助。五路连接通常在没有明显减速的情况下完成。
  • 目前,它的 MySQL,但我很快将其迁移到 PostgreSQL。表大小可以是 Items = 10,000 - 100,000,Divisions

标签: database database-design optimization query-optimization


【解决方案1】:

从关系的角度考虑,因为您将信息放入关系数据库中。

这是我的关系猜测。随时纠正它们。

  • 一个部门有一个或多个仓库。

  • 一个仓库有一个或多个仓库分区。

  • 一个仓库分区有一个或多个仓库货架。

  • 仓库货架上有一件或多件物品。

.

  • 物品位于仓库货架上。

  • 仓库货架位于仓库分区中。

  • 仓库分区位于仓库中。

  • 仓库位于一个部门。

我希望这对您的数据库设计有所帮助。

编辑添加:我将布置表格的索引。您应该能够创建其余的列。

Division
--------
Division ID
...

Warehouse
---------
Warehouse ID
Division ID
...

Warehouse Partition
-------------------
Warehouse Partition ID
Warehouse ID
...

Warehouse Rack
--------------
Warehouse Rack ID
Warehouse Partition ID
...

Item
----
Item ID
Warehouse Rack ID
Item Type ID
...

Item Type
---------
Item Type ID
Item name
Item Price

每个表都有一个主 ID 盲键,可能是自增整数或自增长整数。

除 Division 之外的所有表都有一个指向父表的外键。

Item 表中的一行代表一个项目。一件物品只能在一个仓库货架上。

现代关系数据库连接五个表应该没有性能问题。我已经看到了 30 个表连接。

构建您的系统,解决实际出现的性能问题,而不是花任何时间担心假设的性能问题。

【讨论】:

  • 是的,但物品位于仓库货架的楼层(例如,货架有十层楼,一件物品可能位于同一或不同货架的一层或多层)。这就是我在 itemLocation 表中使用“floor_number”的目的。在这种情况下,ItemLocation 表可以正常工作(正确跟踪所有内容)。但我只是怀疑加入所有这五个表是否会有任何性能问题。另外,在这种情况下,您会建议什么样的表结构?谢谢。
  • 我正在考虑将一个项目作为一个项目,数量为 1。您正在尝试将所有项目分组在一行中,由于您给出的原因,这不会很好地工作。是的,我的项目表将有更多的行。
  • 为了您的方便,我画了一张图。请在此处查看:imagebin.org/246944 另外,请告诉我您基于此的最佳建议。仅供参考,公司的一个部门将有一个或多个这样的“图片”(仓库)。谢谢。
【解决方案2】:

正如 Gilbert Le Blanc 所写,您可能不需要加入五个表 - 您可能只需要加入“WarehouseRacks”。

但是,您写道需要“跟踪” - 这表明涉及时间方面。

这为您提供了以下架构:

Items { item_id, item_name, item_price,......}
Divisions { division_id, division_name, division_address,.......}
Warehouses { warehouse_id, division_id, warehouse_name,........}
WarehousePartitions { partition_id, warehouse_id partition_name,........}
WarehouseRacks { rack_id, partition_id, rack_name,.......} 
ItemLocation (rack_id, item_id, entry_time, quantity, floor_number)

在 ItemLocation 中,所有 3 列都是复合主键的一部分 - 您实际上是在说“任何时候在给定位置只能有一个项目的实例”。

您仍然必须加入五个表才能检索项目 ID(至少如果您需要地址和名称等)。假设您拥有现代硬件和数据库软件,这应该没问题 - u 除非您处理大量数据,否则外键/主键关系上的 5 路连接不太可能导致性能问题。鉴于您在评论中提到的数量,以及您将在 MySQL 上运行它的事实,我认为您无需担心连接的数量。

此模型的好处是您根本无法将无效数据插入到项目位置表中 - 您不能说该项目位于分区中不存在的机架或不存在的仓库中存在于该部门;如果仓库更改部门,您不必更新所有 item_location 记录。

我创建了一个SQLFiddle 来展示它的工作原理。

“item_location”表是其中最大的关注点——您必须选择是存储快照(这是本设计所做的),还是存储事务表。使用“快照”视图,您的代码始终会更新“数量”列,有效地表示“截至 entry_time,此机架的此楼层中有 x 个项目”。

“事务”模型允许您插入多条记录 - 通常在添加项目时为正数,在删除项目时为负数。该位置在任何时间点的项目是这些数量的总和,直到所需时间。

【讨论】:

  • No Neville,“一个项目可以在给定时间出现在多个地方”。例如:在 Y 部门的 X 仓库机架中可能有 10 个英特尔 CPU。在 Q 部门的 P 仓库机架中可能还有另一个,比如 20 个英特尔 CPU。
  • 请在此处查看仓库结构:imagebin.org/246944 并告诉我您的建议。
猜你喜欢
  • 2013-09-01
  • 2016-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-06
  • 1970-01-01
相关资源
最近更新 更多