简体   繁体   English

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

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

I'm going to be running lotteries on my website, and hence there needs to be somewhere to store the tickets and numbers. 我将在我的网站上运行彩票,因此需要在某处存储门票和号码。 I will definitely have a table, called tickets in which each row will have their own ticket id, their associated lottery id and all other information (like id of the user to whom it belongs). 我肯定会有一张表,称为tickets ,其中每一行都有自己的票证ID,相关的彩票ID和所有其他信息(例如它所属的用户的ID)。

However, my question is whether I should make another field in tickets to hold the numbers chosen on the ticket. 但是,我的问题是我是否应该在tickets再设一个字段来保存tickets上所选的号码。 It's not an option to create multiple fields such as number1 , number2 etc, as each lottery will have different types of tickets (ie lottery1 may ask you to choose 4 numbers, and lottery2 may ask you to choose 6). 创建多个字段(如number1number2等)不是一个选项,因为每个彩票都有不同类型的彩票(即lottery1可能会要求您选择4个数字,而lottery2可能会要求您选择6个)。

So I can either make a new field which is either VARCHAR or TEXT to accept comma-separated ticket numbers, ie: 1,2,3,4,5,6 or make another new table called numbers where each row would have the ticket id and number associated with it. 所以我可以创建一个VARCHAR或TEXT的新字段来接受以逗号分隔的票号,即: 1,2,3,4,5,6或者创建另一个名为numbers新表,其中每一行都有票号id和与之相关的数字。 However I'm not sure if this method is very efficient, as for just one ticket of 6 numbers, there would need to be 1 row in the tickets table, and 6 rows in the numbers table. 但是我不确定这种方法是否非常有效,因为只有一个6个数字的tickets ,在tickets表中需要有1行,在numbers表中需要6行。

Which of these options is most efficient? 哪些选项最有效? Or is there an even better way to do it than this? 或者有更好的方法来做到这一点? Please remember that at the end of the lottery the code will need to cycle through each ticket to check if they have won - so option 2 might be too resource-hogging there. 请记住,在抽奖结束时,代码需要循环每张票以检查他们是否已经获胜 - 因此选项2可能过于资源占用。

In the following "Ticket[Number]" should be taken to mean "Selected Set of Lottery Numbers". 在下面的“票[数字]”应被理解为“选定的彩票号码的设置 ”。 Remember that Set(a,b,c) is equal to Set(c,b,a) . 请记住, Set(a,b,c)等于Set(c,b,a)


I would have it like this: 我会这样:

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

That is, Purchase:M-1:Ticket Purchase:M-1:Ticket

The DisplayTicketNumber is the number, as the user selected it, eg "3,1,2" while, on the other hand, the TicketNumber is the normalized ticket number where the small values are put first. DisplayTicketNumber是用户选择它的数字,例如“3,1,2”,而另一方面, TicketNumber是标准化的票号,其中小值被放在第一位。 The final form is thus min,..,max or similar. 因此,最终形式为min,..,max或类似。 That is, any number of DisplayTicketNumbers that have the same set of values (in any order) will have the same TicketNumber : 也就是说,具有相同值集(任何顺序)的任何数量的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

Then put an index on TicketNumber so what a simple WHERE TicketNumber = @normalizedTicketNumber will be a very fast index. 然后在TicketNumber上放一个索引,这样一个简单的WHERE TicketNumber = @normalizedTicketNumber将是一个非常快的索引。

I would actually argue this is an acceptably normalized design and the TicketNumber (along with say a Raffle number) forms a Key. 我实际上认为这是一个可接受的标准化设计,TicketNumber(以及一个抽奖号码)形成一个密钥。 My arguments for this are thus: 因此,我的论点是:

  1. A TicketNumber is an opaque value that uniquely identifies a Ticket (per Raffle). TicketNumber是一个不透明的值 ,它唯一地标识一个Ticket(每个Raffle)。 One does not need to "know the details" inside the DB model. 一个人不需要在DB模型中“了解细节”。 (There might be a need in some cases, but not here.) (在某些情况下可能需要,但不是在这里。)

  2. The DisplayTicketNumber is an artifact of the users input; DisplayTicketNumber是用户输入的工件; yet multiple DisplayTicketNumbers can represent the same TicketNumber. 但是多个DisplayTicketNumbers可以表示相同的TicketNumber。 While this does represent possible "duplication" it is important to realize that this is a Friendly Display value that represents a list (which has more information than a set ) of numbers chosen. 虽然这确实代表了可能的“重复”,但重要的是要意识到这是一个友好显示值,表示所选数字的列表 (其中包含的信息多于一 )。

    1. In a case like this I would make the DisplayTicketNumber (and TicketNumber ) immutable with triggers so that, after creation, no database inconsistencies can be introduced here. 在这种情况下,我会使DisplayTicketNumber (和TicketNumber )与触发器不可变,这样在创建之后,不会在这里引入数据库不一致。

    2. If a FK can be computed then the constraint between DisplayTicketNumber and TicketNumber can be enforced without immutability. 如果可以计算FK,则可以强制执行DisplayTicketNumber和TicketNumber之间的约束而不具有不变性。

(I have omitted various details like having different TicketNumbers for different Raffles, etc. I also show a TicketId for a FK, but I also hinted that RaffleId,TicketNumber is an acceptable [non-surrogate] Key.) (我省略了各种细节,例如为不同的莱佛士提供不同的TicketNumbers等。我还为FK展示了TicketId ,但我也暗示了RaffleId,TicketNumber是一个可接受的[非代理]密钥。)

Also, the Ticket table could be eliminated: since very few Lottery Number Sets will be shared so, if there is no extra associated Ticket information, then removing it might be an acceptable denormalization. 此外,票证表可以被删除:因为很少有彩票号码集将被共享,因此,如果没有额外的关联票证信息,则删除它可能是可接受的非规范化。 One advantage of this is then the TicketNumber could be moved into the Purchase table and then turned into a computed column (which is still indexed) that normalized the Ticket value. 这样做的一个优点是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. 并且, 如果 MySQL允许在FK中使用计算列,则使用关系PK(Ticket.TicketNumber) - > FK(Purchase.TicketNumber) ,其中计算Purchase.TicketNumber可以用于增加模型完整性而不消除Ticket表。 (I do not use MySQL, however, so I cannot say if this is viable or not.) (但我不使用MySQL,所以我不能说这是否可行。)

Happy coding. 快乐的编码。

I'd use the second option where you make the new table, called numbers, and you have the numbers associated with it. 我会使用第二个选项来制作新表,称为数字,并且您有与之关联的数字。

But I'd also add a field in the tickets table, where you indicate the amount of numbers that can be selected, and a condition where you check if the amount of numbers inserted using that ticket (using COUNT in a query) is less than the amount of numbers that can be selected, then insert. 但是我还会在故障单表中添加一个字段,您可以在其中指明可以选择的数字量,以及检查使用该故障单插入的数字量(在查询中使用COUNT)是否小于的条件可以选择的数字量,然后插入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM