我可以在MySQL中创建一个包含动态列的表结构吗?

时间:2013-11-19 16:24:17

标签: mysql sql database multiple-columns

我创建了一个库存控制数据库,其中包含两个表(实际上超过两个,但这些是与我的问题相关的两个表):库存和收据

我希望库存表中的库存与收据表中的库存之间的链接更加清晰,如果客户每张收据只能订购一件库存,那就没问题,因为我&# 39; d只需在Recipts表中有一个StockID列和Quantity列,StockID列为Stock表中ID的FK,但是,客户可以在其上创建包含任意数量库存的收据,这意味着我必须在收据表中包含大量列(即StockID_1,Quantity_1,StockID_2,Quantity_2等)

有没有办法解决这个问题(你有没有在MySQL中有一个动态扩展的列集),除了我目前所做的,就是拥有一个具有以下结构的OrderContents列(数据库或其他任何内容不强制执行)StockID1xQuantity,StockID2xQuantity等等?

我会发布数据库结构的图像,但我还没有足够的重复。通过将数据库规范化为第4或第5范式,我的讲师提到了可以做到的事情吗?

2 个答案:

答案 0 :(得分:1)

我建议有3张桌子:

股票(StockID)+特定股票字段

收据(收据ID)+收据特定字段。

StockReceipt (收据ID,StockID,数量)(可以有StockReceiptID,或使用StockID + ReceiptID作为主键)


包含价格的解决方案可能如下:

股票(股票代码,价格)

PriceHistory (StockID,Price,Date)或(DateFrom,DateTo)

收据(ReceiptID,ReceiptDate)

StockReceipt (收据ID,StockID,数量)

这样您就可以计算过去任何收据的TotalStockReceiptPrice和TotalReceiptPrice。


我怀疑可能正是您正在寻找的东西:

股票(StockID,StockPrice)

收据(收据ID)

StockReceipt (收据ID,StockID,数量)

SELECT r.ReceiptID, SUM(s.StockPrice * sr.Quantity) AS ReceiptPrice
FROM Receipt r
INNER JOIN StockReceipt sr ON r.ReceiptID = sr.ReceiptID
INNER JOIN Stock s ON sr.StockID = s.StockID
GROUP BY r.ReceiptID

这一切都非常规范化(再次,不知道正常形式 - 第3?)。但是,只有当Stock Record上的StockPrice从未改变时,它才有效。一旦更改,您的ReceiptPrices将全部反映新价格,而不是客户实际支付的价格。

如果价格可以改变,您需要保留价格历史表(ItemID,Price,DateTo,DateFrom)或在StockReceipt记录上记录StockPrice(然后摆脱JOIN到上述查询中的Stock记录并使其使用sr.StockPrice而不是s.StockPrice

要执行下面发布的INSERT,您必须执行以下操作:

INSERT INTO StockReceipts  (ReceiptID, StockID, Quantity, TotalStockPrice) 
SELECT 1, 99, 2, s.StockPrice
FROM Stock s 
WHERE s.StockID = 99

然而,发出此收据的任何内容(并触发INSERT)很可能已经知道价格,因此可以插入价值。

答案 1 :(得分:0)

不,关系数据库不允许动态列。关系表的定义是它有一个标题列的标题,每个行都有相同的列。

重复库存列组的技术违反了First Normal Form,并且还存在许多实际问题,例如:

  • 您如何知道要创建多少额外的列?
  • 如果您不知道它在哪个列中,您如何搜索给定值?
  • 如何强制执行唯一性?

最简单的解决方案是@OGHaza描述的,在另一个表中的上存储额外的库存/数量数据。这样就解决了上述问题。

  • 您不需要创建额外的列,只需要额外的行,这很容易使用INSERT。
  • 您可以在一个列中搜索给定值以查找它。
  • 您可以在列上添加约束。

如果你真的想要理解关系概念,那么一本易于阅读的好书是:{J. 3。}来自C. J. Date。


在某些情况下,您希望使用不重复的动态列扩展表定义 - 它们只是新属性。这不是关系,但并不意味着我们不需要一些数据建模技术来处理您描述的场景。

对于此类问题,您可能希望阅读我的演示文稿SQL and Relational Theory: How to Write Accurate SQL Code,了解不同解决方案的概述及其优缺点。


PS:第四和第五范式与此方案有 nothing 。你的讲师显然不理解他们。