具有单独值的总行数与多行的一行性能?

时间:2014-03-31 15:54:51

标签: database-design sqlite

不是100%肯定如何解释这种情况,但在这里:

我正在建立一个库存数据库,输入所有收到的物品,并为每个容器创建一个标签,该标签将有条形码将物理项目与数据库中的记录联系起来。

因此,每个Container都有一个标签,通常是收到订单的子项。

目前,该标签的条形码包含Container代表的Product数量和收到记录的RowID。

问题是什么是最佳做法:

  1. 每个收到的订单包含一行,其中包含TotalProductQty 整个收到订单和收到的总容器。然后有 Container上的标签具有RowID和特定的 ContainerQty。然后使用UsedQty列更新表 正在使用的Container内的产品数量 (基于条形码中嵌入的ContainerQty)。还有一栏 使用UsedContainersQty,但系统中没有任何记录 容器级别。
  2. 我最好只将每个容器输入自己的行 并添加一个Used Bool列?这显然会更快地更新, 但也会使表更大并且(我会想) 选择减慢插入和可能的效果性能 因为收到的订单将从1个插入/行转到选择 从5到50?
  3. 我也很想知道离开时是否有意义 ReceivedOrders表与TotalProductQty和ProductID和 然后,ContainerQty为a中的每个容器创建一个新表 ReceivedContainers表将具有外键 ReceivedOrders表和每个可以绑定的容器的行 到标签。
  4. 这些是我可以考虑实施的最佳选择,但我没有丝毫关于什么能提供最佳性能?

    不确定性能是否受到本机应用程序编写语言的影响,因此我也标记了应用程序语言和平台。

    作为一个例子,如果我遵循方法一,我会有一个这样的表:

    RowId|TotalProductReceived|TotalContainersReceveived|UsedProductQty| UsedContainerQty |ProductTypeID|VendorID|ReceivedDate|LastUsedDate
    1    |        225         |            5            |     100      |        2         |     1       |    1   | 3/31/2014  |  4/1/2014
    

    这表明我有5个容器,共有225个项目。并且已经使用了2个容器,共计100个项目。所以我有剩余的125件物品存放在3个容器中。每个容器在容器上都有一个标签,其中包含一个逗号分隔的条形码,其中包含RowID(在这种情况下为1)和容器中的数量,当扫描条形码时,RowID with RowID 1更新为UsedContainerQty = UsedContainerQty + 1和UsedProductQty = UsedProductQty + Quantityembedded in barcode。

    我在上面看到的优点是它是一个更紧凑的数据库,易于查询,并且应该比下一个示例快得多,问题是它在信息中留下了很多空白。

    选项2更像是以下内容:

    ContainerId|ProductQtyInContainer|ProductTypeID|VendorID|ReceivedDate|Used
    1          |        50           |     1       |   1    | 3/31/2014  |4/1/2014
    2          |        50           |     1       |   1    | 3/31/2014  |4/1/2014
    3          |        50           |     1       |   1    | 3/31/2014  |null
    4          |        50           |     1       |   1    | 3/31/2014  |null
    5          |        25           |     1       |   1    | 3/31/2014  |null
    

    然后容器将有一个条形码,当输入时只有ContainerID,它将使用它的日期更新Used列,未使用的项将为null。

    这将对产品的使用频率和每个容器的更多信息进行更深入的分析,但代价是不仅需要更多行,而且还有更多冗余信息:

    要修复Redudent信息,我的想法可能会将数据分成两个表:

    第一个像:

    RecevedID|ReceivedDate|ProductTypeID|VendorID
        1    | 3/31/2014  |     1       |   1 
    

    然后第二个像:

    RecevedID|ContainerId|ProductQtyInContainer|Used
        1    |    1      |        50           |4/1/2014
        1    |    2      |        50           |4/1/2014
        1    |    3      |        50           |null
        1    |    4      |        50           |null
        1    |    5      |        25           |null
    

    这个似乎有更少的冗余信息,但需要更复杂的插入,我担心这种方法的并发问题。长插入锁定数据库,而其他尝试更新表格结束?

    我只是不确定哪种方法和做法最好,最有用?

    此应用程序的范围将是输入进入建筑物的每个项目都有一个数字记录,并标记每个项目的内部只有可扫描的ID,当使用产品时,可以扫描更新记录,所以我们可以更好地了解我们在特定时间段内使用的每件商品的数量,并且还能够查看我们目前库存的商品。

    但是我担心许多僵局导致物品进入并且物品被扫描出来并且不确定上述哪种方法最有助于避免信息丢失。和失败的记录更新。然而,仍然提供全面库存控制和知识的所有好处!

    报告也将每天多次从信息中提取。

    非常感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

我没有将SQLite用于这种应用程序,因此可能存在一些我不了解的特定SQLite限制,但总的来说我建议首先构建一个规范化的模式,重点是让它易于理解而且难以打破。

然后我建议构建测试脚本,看看你是否能达到预期的性能目标;如果不能,那么在进行非规范化之前,有很多方法可以优化数据库。这迫使您量化您的顾虑 - 您是否担心数十,数百,数千种产品?您每年有多少交易?有多少并发用户?它还会迫使您思考可能的使用场景 - 您可能需要哪些查询?这确实有助于思考您的设计,并允许您识别需要担心的场景 - 您对死锁的恐惧是合理的,但它们几乎总是由慢查询引起 - 避免它们,并且您的数据库不应该锁定。

编写测试工具以针对一组有代表性的测试数据运行查询 - 如果您预计需要一百万条交易记录,则使用300万条测试记录填充数据库。

只有在您证明自己遇到性能问题后,才会看到非规范化并寻求更深奥的解决方案。

因此,在您的情况下,我建议使用一种相当标准的方法来管理库存数据 - 使用交易表。交易基本上是指进入的集装箱,正在使用的集装箱,或者在登记后被发现为空/缺的集装箱。

例如:

TransactionQuantity|ContainerId|ProductTypeID|VendorID|TransactionDate|Comment
                 50|          1|            1|       1|      3/31/2014|Container received
                 50|          2|            1|       1|      3/31/2014|Container received
                -50|          2|            1|       1|       1/4/2014|Container used

此架构的好处是可以告诉您每个容器发生了什么,以及何时;它允许您处理部分使用,并允许您使用sum(transactionQuantity)来查找库存水平;通过使用交易日期列,您还可以使用简单的SQL轻松查看过去任何时刻的库存水平。

表确实很长 - 但只要你使用索引,只要你没有进入极端,长表就不是SQL的特殊问题;根据数据库引擎和硬件,数以千万计的行并不是极端的。