数据库表规范化(很多关系)

时间:2013-02-14 05:59:39

标签: database database-design optimization query-optimization

我有以下表格:

项目{item_id,item_name,item_price,......}
分部{division_id,division_name,division_address,.......}
仓库{warehouse_id,仓库名称,........}
WarehousePartitions {partition_id,partition_name,........}
WarehouseRacks {rack_id,rack_name,.......}

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

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

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

此外,如果我们不接受整个字段,则该表没有任何主键。这会引起任何问题吗?有没有更好的方法来实现这一目标?

感谢。

2 个答案:

答案 0 :(得分:2)

考虑关系,因为您将信息放在关系数据库中。

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

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

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

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

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

  • 项目位于仓库货架中。

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

  • 仓库分区位于仓库中。

  • 仓库位于分部。

我希望这有助于您的数据库设计。

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

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个表连接。

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

答案 1 :(得分:1)

正如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(至少如果您需要地址和名称等)。假设您拥有现代硬件和数据库软件,这应该没问题 - 除非您正在处理大量数据,否则外键/主键关系的5向连接不太可能导致性能问题。鉴于你在评论中提到的数量,以及你将在MySQL上运行它的事实,我认为你不必担心连接的数量。

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

我创建了一个SQLFiddle来展示它是如何工作的。

“item_location”表是最大的问题 - 您必须选择是存储快照(这是设计的作用)还是事务表。使用“快照”视图,您的代码始终会更新“数量”列,有效地说“从entry_time开始,此层中此楼层中有x个项目”。

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