组织这些表+行的最有效方法是什么? - MySQL

时间:2012-07-27 00:06:39

标签: php mysql database-design rows database-performance

我将在我的网站上运行彩票,因此需要在某处存储门票和号码。我肯定会有一个名为tickets的表,其中每一行都有自己的票证ID,相关的彩票ID和所有其他信息(例如它所属的用户的ID)。

但是,我的问题是我是否应该在tickets中创建另一个字段以保留票证上选择的号码。创建多个字段(如number1number2等)不是一个选项,因为每个彩票都会有不同类型的彩票(即lottery1可能会要求您选择4个数字,lottery2 1}}可能会要求你选择6)。

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

哪些选项最有效?或者有更好的方法来做到这一点?请记住,在抽奖结束时,代码需要在每个票据中循环以检查它们是否已经赢了 - 所以选项2可能在那里占用太多资源。

2 个答案:

答案 0 :(得分:1)

在下文中,“Ticket [Number]”应表示“选择设置彩票号码”。请注意,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(以及一个Raffle数字)构成了一个Key。因此我的论点是:

  1. TicketNumber是一个不透明值,它唯一地标识一个Ticket(每个Raffle)。一个人不需要在DB模型中“了解细节”。 (在某些情况下可能需要,但不是在这里。)

  2. DisplayTicketNumber是用户输入的工件;但是多个DisplayTicketNumbers可以表示相同的TicketNumber。虽然 表示可能的“重复”,但重要的是要意识到这是一个友好显示值,表示列表(其中包含更多信息)而不是 set )所选的数字。

    1. 在这样的情况下,我会使DisplayTicketNumber(和TicketNumber)使用触发器不可变,这样在创建之后,不会在这里引入数据库不一致。

      < / LI>
    2. 如果可以计算FK,那么可以强制执行DisplayTicketNumber和TicketNumber之间的约束而不会产生不变性。

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

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

    并且,如果 MySQL允许在FK中使用计算列,则使用关系PK(Ticket.TicketNumber) - &gt; FK(Purchase.TicketNumber),其中计算Purchase.TicketNumber可以用于提高模型完整性,而不会删除Ticket表。 (但我不使用MySQL,所以我不能说这是否可行。)

    快乐的编码。

答案 1 :(得分:0)

我会使用第二个选项来制作新表,称为数字,并且您有与之关联的数字。

但是我还会在故障单表格中添加一个字段,您可以在其中指明可以选择的数字量,以及检查使用该故障单插入的数字量的条件(在查询中使用COUNT)小于可以选择的数字量,然后插入。