我可以在MySQL中创建具有动态列的表结构吗?

我可以在MySQL中创建具有动态列的表结构吗?,mysql,sql,database,multiple-columns,Mysql,Sql,Database,Multiple Columns,我创建了一个库存控制数据库,其中包含两个表(实际上不止两个,但这两个表与我的问题相关):库存和收据 我希望stock表中的stock和receipts表中的stock之间的链接更清晰一些,如果客户每次收据只能订购一项stock,这将很好,因为我只是在Recipts表中有一个StockID列和一个Quantity列,StockID列作为stock表中ID的FK,但是,客户可以在收据上填写任意数量的库存项目,这意味着收据表中必须有大量列(即StockID_1、Quantity_1、StockID_2

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

我希望stock表中的stock和receipts表中的stock之间的链接更清晰一些,如果客户每次收据只能订购一项stock,这将很好,因为我只是在Recipts表中有一个StockID列和一个Quantity列,StockID列作为stock表中ID的FK,但是,客户可以在收据上填写任意数量的库存项目,这意味着收据表中必须有大量列(即StockID_1、Quantity_1、StockID_2、Quantity_2等)

在MySQL中,除了我目前所做的之外,有没有其他方法可以解决这个问题(你能像MySQL中的一组动态扩展的列一样),那就是使用以下结构(数据库或任何东西都不强制执行)的OrderContents列StockID1xQuantity、StockID2xQuantity等等


我会发布一张DB结构的图片,但我还没有足够的声誉。我的讲师提到可以通过将数据库标准化为第四或第五标准形式来实现这一点。

我建议有3个表:

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

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

库存收据(收货ID、库存ID、数量)(可以有库存收货ID,或者使用库存ID+收货ID作为主键)


包括价格在内的解决方案可能如下所示:

股票(股票ID、价格)

价格历史记录(股票ID、价格、日期)或(DateFrom、DateTo)

收据(收据ID、收据日期)

库存收据(收据ID、库存ID、数量)

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


我想这可能就是你想要的:

股票(股票ID、股票价格)

收据(收据ID)

库存收据(收据ID、库存ID、数量)

这一切都是非常正常的(再次,不知道什么是正常形式-第三?)。然而,只有当股票记录上的股票价格从未改变时,它才起作用。一旦它发生变化,你的收据价格将全部反映新的价格,而不是客户实际支付的价格

如果价格可以更改,您需要保留一个价格历史记录表(ItemID、price、DateTo、DateFrom)或在StockReceive记录上记录股票价格(然后在上述查询中去掉
连接到股票记录,并使其使用
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

但是,很有可能发出此收据的任何人(并触发插入)已经知道价格,因此可以只插入值。

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

您重复股票列组的技术违反了第一范式,而且还存在许多实际问题,例如:

  • 您如何知道要创建多少额外的列
  • 当你不知道某个给定值在哪一列时,你如何搜索它
  • 你如何加强独特性
最简单的解决方案是,如@OGHaza所述,在另一个表的行上存储额外的库存/数量数据。这样就解决了上述问题

  • 您不需要创建额外的列,只需要创建额外的行,这很容易使用INSERT
  • 您可以在一列上搜索给定值以找到它
  • 可以在列上放置约束
如果你真的想理解关系概念,一本容易阅读的好书是:by C.J.Date


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

对于这类问题,您可能想阅读我的演示文稿,了解不同解决方案的概述及其优缺点



PS:第四和第五范式与此场景无关。您的讲师显然不理解它们。

这是对数据库的标准化,但我无法告诉您使用什么样的标准形式。这可能会起作用,谢谢:)将StockID+ReciptID作为复合主键是有意义的。这是标准的第三标准形式,一种常规的多对多关系。一个库存项目可以在多张收据上,而一张收据可以包含多个库存项目。@nielsm,谢谢你提供的信息,总有一天我真的需要回去正常阅读它是否符合要求(如果我使用库存收据表),以便在Recipts表中为整个订单设置一个总价列,以及StockRecipt表中的TotalStockPrice列,该列存储该商品订购数量的总价?
INSERT INTO StockReceipts  (ReceiptID, StockID, Quantity, TotalStockPrice) 
SELECT 1, 99, 2, s.StockPrice
FROM Stock s 
WHERE s.StockID = 99