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


What is the most efficient way to organise these tables + rows? - MySQL

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

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

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

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

在以下内容中,"Ticket[Number]"应表示"SelectedSetof 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(与Raffle数字一起)形成了一个Key。因此,我的论点是:

  1. TicketNumber是一个不透明值,用于唯一标识Ticket(每个抽奖)。不需要在DB模型中"了解细节"。(在某些情况下可能需要,但这里没有。)

  2. DisplayTicketNumber是用户输入的工件;然而多个DisplayTicketNumber可以表示相同的TicketNumber。虽然该确实表示可能的"重复",但重要的是要认识到,这是一个友好显示值,表示所选数字的列表(其信息比集合更多)。

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

    2. 如果可以计算FK,则DisplayTicketNumber和TicketNumber之间的约束可以在没有不变性的情况下强制执行。

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

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

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

快乐的编码。

我会使用第二个选项,在这里你可以创建一个新的表,称为数字,并且你有与之相关的数字。

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