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

问题描述 投票:3回答:2

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

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

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

哪些选项最有效?或者有更好的方法来做到这一点?请记住,在抽奖结束时,代码需要循环每张票以检查他们是否已经获胜 - 因此选项2可能过于资源占用。

php mysql database-design rows database-performance
2个回答
1
投票

在下文中,“票号[编号]”应理解为“选定的彩票号码集”。请记住,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是一个不透明的值,它唯一地标识一个Ticket(每个Raffle)。一个人不需要在DB模型中“了解细节”。 (在某些情况下可能需要,但不是在这里。)
  2. DisplayTicketNumber是用户输入的工件;但是多个DisplayTicketNumbers可以表示相同的TicketNumber。虽然这确实代表了可能的“重复”,但重要的是要意识到这是一个友好显示值,表示所选数字的列表(其中包含的信息多于一组)。 在这种情况下,我会使DisplayTicketNumber(和TicketNumber)使用触发器不可变,这样在创建之后,不会在这里引入数据库不一致。 如果可以计算FK,则可以强制执行DisplayTicketNumber和TicketNumber之间的约束而不具有不变性。

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

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

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

快乐的编码。


0
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.