3

我将在我的网站上运行彩票,因此需要有一个地方来存储彩票和号码。我肯定会有一个表,调用tickets其中每一行都有自己的票号、相关联的彩票 ID 和所有其他信息(如它所属的用户的 ID)。

然而,我的问题是我是否应该在另一个字段中tickets保存票上选择的数字。不能创建多个字段,例如number1,number2等,因为每张彩票都有不同类型的彩票(即lottery1可能要求您选择 4 个号码,也lottery2可能要求您选择 6 个号码)。

所以我可以创建一个 VARCHAR 或 TEXT 的新字段来接受逗号分隔的票号,即:1,2,3,4,5,6或创建另一个名为的新表numbers,其中每行都有票号和与之关联的票号。但是我不确定这种方法是否非常有效,因为只有一张 6 个号码的票,表中需要 1 行,tickets表中需要 6 行numbers

这些选项中哪个最有效?或者有比这更好的方法吗?请记住,在彩票结束时,代码将需要循环检查每张彩票以检查他们是否中奖 - 所以选项 2 可能过于占用资源。

4

2 回答 2

1

在下文中,“Ticket[Number]”应该被理解为“Selected Set of Lottery Numbers”。记住Set(a,b,c)等于Set(c,b,a)


我会这样:

Purchase
  -PersonID // associate Person (one person can have many purchases)
  -TicketID // associate Ticket (a purchase is for one "ticket",
            //                   which can be purchased many times)
  -DisplayTicketNumber // for Human Display

Ticket
  -TicketNumber

那是,Purchase:M-1:Ticket

是用户选择的DisplayTicketNumber数字,例如“3,1,2”,而另一方面,TicketNumber是标准化的票号,其中小值放在首位。最终形式因此min,..,max或相似。也就是说DisplayTicketNumbers,具有相同值集(以任何顺序)的任意数量将具有相同的TicketNumber:

DisplayTicketNumber  TicketNumber
1,2,3                1,2,3
2,3,1                1,2,3
3,2,1                1,2,3
3,2,1,4              1,2,3,4 .. and etc

然后放一个索引,TicketNumber这样一个简单的索引WHERE TicketNumber = @normalizedTicketNumber将是一个非常快的索引。

我实际上认为这是一个可以接受的规范化设计,TicketNumber(连同一个抽奖号码)形成一个密钥。因此,我对此的论点是:

  1. TicketNumber 是一个不透明的值,它唯一地标识一张票(每个抽奖)。无需了解数据库模型内部的“细节”。(在某些情况下可能需要,但这里不是。)

  2. DisplayTicketNumber 是用户输入的产物;然而多个 DisplayTicketNumber 可以代表同一个 TicketNumber。虽然这确实代表了可能的“重复”,但重要的是要意识到这是一个友好显示值,它代表一个列表(比一信息更多)选择的数字。

    1. 在这种情况下,我会使用触发器使DisplayTicketNumber(and TicketNumber) 不可变,以便在创建后不会在此处引入数据库不一致。

    2. 如果可以计算 FK,则可以强制执行 DisplayTicketNumber 和 TicketNumber 之间的约束而不会保持不变。

(我省略了各种细节,例如为不同的莱佛士设置不同的 TicketNumbers 等。我还TicketId为 FK 显示了一个,但我也暗示这RaffleId,TicketNumber是一个可接受的 [非代理] 键。)

此外,Ticket 表可以被删除:因为很少有彩票号码集将被共享,所以如果没有额外的关联 Ticket 信息,那么删除它可能是一种可接受的非规范化。这样做的一个优点是TicketNumber可以将其移动到Purchase表中,然后转换为标准化 Ticket 值的计算列(仍被索引)。

And, if MySQL allows using a computed column in a FK then using the relationship PK(Ticket.TicketNumber) -> FK(Purchase.TicketNumber), where Purchase.TicketNumber is computed, could be used to increase model integrity without eliminating the Ticket table. (I do not use MySQL, however, so I cannot say if this is viable or not.)

Happy coding.

于 2012-07-27T00:33:14.037 回答
0

我将使用第二个选项,您可以在其中创建新表,称为数字,并且您有与之关联的数字。

但我还要在门票表中添加一个字段,在其中指示可以选择的数字数量,以及检查使用该门票插入的数字数量(在查询中使用 COUNT)是否小于可以选择的数字数量,然后插入。

于 2012-07-27T00:13:51.657 回答