【问题标题】:Have 2 separate tables or an additional field in 1 table?有 2 个单独的表或 1 个表中有一个附加字段?
【发布时间】:2011-02-19 20:15:51
【问题描述】:

我正在就我在多家公司的股票交易提出一份小型个人申请。

这些行为可以是出售公司股票或购买。因此,两种情况下要保存的详细信息为:

  1. 共享数量
  2. 平均价格

“买入”和“卖出”使用单独的表格,还是只使用一个表格进行“交易”并保留一个区分“买入”和“卖出”的字段会更好吗?

【问题讨论】:

  • PS:买卖记录需要相互独立维护。因此,如果我们考虑 1 个表,则每个公司有 2 条记录。
  • 也许你应该想想为什么我们都说每行一个交易,而不是 2 个单独的列...
  • 您不需要两行单独的购买/出售信息。根据您对仅存储一组销售信息和一组购买的各种答案的 cmets,3NF 实际上指向每家公司的一行,该信息具有单独的列。请参阅我的更新答案。

标签: sql database normalization


【解决方案1】:

肯定是后一种情况 - 一个表,一个简单的字段(布尔值)定义是卖出还是买入。您应该按实体定义表,而不是按对它们执行的操作。

【讨论】:

  • 那么,我会保留我现在的设计。我有一个布尔值作为“真”来购买。谢谢:)
【解决方案2】:

这实际上是一个棘手的问题。您所说的表格基本上是一个交易表格,详细说明了您的所有买卖。

从这个意义上说,您会认为在一个表中同时进行买卖是有意义的。

但是,在许多司法管辖区,卖出订单有额外的信息。该信息是用来抵消它的购买订单(出于资本收益或利润目的)。虽然在严格的先买先卖 (FBFS) 环境中这不是必需的,但这绝不是唯一的可能性。

例如,根据澳大利亚法律,您实际上可以用最近一次购买来抵消销售,只要您事先以清晰的语言写下理由。即使我的公司遵循 FBFS,我也可以收到红利或补充股票,然后我可以立即出售。这些抵消了最近购买的股票,而不是我持有 X 年的股票(这通常可以方便地减少应缴税款)。

如果您遵循严格的 FBFS,那么您就不需要额外的信息并且您的交易是对称的。即使他们不是,我已经在一张表中实现了它,其中包含额外的信息,当然对于购买订单毫无用处。这似乎是最简单的方法。

可以将其作为两个不对称的表来执行,但这会使查询更加成问题,因为您经常需要从两个表中提取数据。如果需要,我的建议是坚持使用包含额外信息的单个表格。

我也永远不会存储平均价格。我更喜欢数量、每股价格和经纪成本。其他每个数字都可以从这三个中计算出来,例如:

AvgPrice = (Brokerage + SharePrice * ShareQuant) / ShareQuant

但有时不可能仅从平均价格向后推算,因为您不知道经纪是什么。

而且我不会有布尔值来表示买入/卖出,对卖出订单使用负数同样容易,并且它使资产负债表类型的计算更加容易,因为您只需对值求和,而与订单类型无关而不是需要根据该订单类型来否定其中的一些。


更新:如果您似乎表明,您只打算存储每家公司的汇总信息,我会选择以下内容:

Companies:
    CompanyId primary key
    CompanyCode indexed
    CompanyName
    CompanyBuyQuant
    CompanyBuyAvgPrice
    CompanySellQuant
    CompanySellAvgPrice

然后您根据是买入还是卖出来更新各个列。您不需要单独的行来购买/出售东西。首次添加公司时,数量和价格均设置为 0。

您的实体现在是公司,所以这更有意义。您可能要考虑的一件事是存储买卖股票的总值,而不是平均买卖价格。这将简化您的更新计算,您仍然可以通过将聚合除以数量轻松获得平均值。

所以,下表:

Companies:
    CompanyId primary key
    CompanyCode indexed
    CompanyName
    CompanyBuyQuant
    CompanyBuyValue
    CompanySellQuant
    CompanySellValue
  • 添加公司时,将所有数量和值设置为 0,
  • 当以每股N 美元购买M 股票时,将M 添加到CompanyBuyQuantN * MCompanyBuyValue
  • 当以每股N 美元的价格出售M 股票时,将M 添加到CompanySellQuant 并将N * M 添加到CompanySellValue
  • 获取平均买入价为CompanyBuyValue / CompanyBuyQuant
  • 获取平均售价为CompanySellValue / CompanySellQuant

【讨论】:

  • 内容丰富。在我的情况下,平均价格是你认为的股价,因为没有经纪。这样就解决了。毫无疑问,可以使用负数,但我对第一次更新感到困惑。当添加新的公司名称时,会在交易表中为该公司添加 2 条对应记录,每条记录用于买入和卖出。两条记录将是相同的。 CompanyId:“两者相同”,数量:0,AvgPrice:0。
  • +1 用于详细说明答案。额外的卖出信息可以保存在单独的表格中,以防您需要将单次卖出抵消多次买入。
  • @hkansal,当您将公司添加到您的系统时,将有没有买卖。当您第一次购买该公司的股票时(可能是您添加它的同一时间),您将获得一行(例如,以 128 美元 = 12,800 美元购买 100 股 ibm)。在您出售它们之前,您不会获得卖出订单。每笔交易都应该有它自己的行,并且可以通过处理所有这些行来计算出您在该公司的当前位置。
  • 我想我在不同的页面上。请让我澄清一下。在任何时候,一个公司的交易表都只有 2 行。假设我为 A 公司购买了 100 股 @ 50 股,购买记录行的数量为 100。下一次购买 50 @ 40 股会将同一行更新为 150 并计算新的平均价格。无需维护每次买卖(交易或交易)的记录,因为它是在我的交易系统中完成的。这只是个人申请,因为交易系统会忘记 3 月 31 日之后的所有记录 :(
  • 如果您不维护个人交易,而是维护买卖声明,您甚至不需要两行。只需为公司提供一排带有买卖栏的公司。我会更新我的答案。
【解决方案3】:

我会选择一张桌子。

您可以使用负数来表示卖出。这是一种相当标准的指示。减法和加负数一样!

【讨论】:

  • 我应该只使用负数进行分界还是单独的字段?我想不出我将如何识别要更新的买卖记录。最初数量为零。去掉多余的字段实际上会很好,只是变得贪婪!
【解决方案4】:

一张桌子。每行/项目都是一笔交易,无论是买入还是卖出。

此外,数量列的汇总将为您提供当前位置。现金也是(-1 x 数量 x 价格**)。

如果根据数量的符号推断买入或卖出:不需要单独的列,除非您想创建一个从数量派生的计算列。

**cash:当您卖出(负数量)时,您将获得现金返还(正现金),因此乘数为 -1,以防万一。

【讨论】:

  • 是的,我明白这一点。但是第一次,买卖的数量都为零。仅在第一次时,我将如何确定要更新哪个?
  • @hkansal£:正如其他人提到的和我假设的那样,每次买卖应该有一行,一个数量和一个价格列。否则你的模型有缺陷。
【解决方案5】:

“贸易”可能含糊不清,我并不完全清楚你想在这里做什么。您是否有兴趣仅存储您在每份股票中的当前头寸,还是存储显示头寸如何发展的交易历史?

如果你只是想记录你的持股量(如果你可以做空的话,“头寸”可能是一个更好的词),那么我会简单地记录每一股的持股数量。您提到了平均价格,但如果您希望随时能够出售部分持股,我会对此持谨慎态度。 50买100,60买100,70卖50,平均价格是多少?

除非您期望您的买卖交易数以百万计,否则我更倾向于将每个单独的购买或销售记录为单个表格中的单独行,并将按需总计显示为简单的查询。

【讨论】:

  • 是的,我只需要存储当前位置,分别用于买入和卖出。接下来,平均价格将是加权平均值,分别针对买入和卖出计算。
猜你喜欢
  • 1970-01-01
  • 2011-03-31
  • 2016-02-23
  • 1970-01-01
  • 1970-01-01
  • 2012-01-13
  • 2012-12-16
  • 2020-04-01
  • 1970-01-01
相关资源
最近更新 更多