dth42345 2012-07-27 00:06
浏览 51
已采纳

组织这些表+行的最有效方法是什么? - 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).

However, my question is whether I should make another field in tickets to hold the numbers chosen on the ticket. It's not an option to create multiple fields such as number1, number2 etc, as each lottery will have different types of tickets (i.e lottery1 may ask you to choose 4 numbers, and lottery2 may ask you to choose 6).

So I can either make a new field which is either VARCHAR or TEXT to accept comma-separated ticket numbers, i.e: 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. 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.

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条回答 默认 最新

  • dongzhuji1042 2012-07-27 00:33
    关注

    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).


    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

    The DisplayTicketNumber is the number, as the user selected it, e.g. "3,1,2" while, on the other hand, the TicketNumber is the normalized ticket number where the small values are put first. The final form is thus min,..,max or similar. That is, any number of DisplayTicketNumbers that have the same set of values (in any order) will have the same 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.

    I would actually argue this is an acceptably normalized design and the TicketNumber (along with say a Raffle number) forms a Key. My arguments for this are thus:

    1. A TicketNumber is an opaque value that uniquely identifies a Ticket (per Raffle). One does not need to "know the details" inside the DB model. (There might be a need in some cases, but not here.)

    2. The DisplayTicketNumber is an artifact of the users input; yet multiple DisplayTicketNumbers can represent the same 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.

      2. If a FK can be computed then the constraint between DisplayTicketNumber and TicketNumber can be enforced without immutability.

    (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.)

    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.

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 关于#python#的问题,请各位专家解答!
  • ¥15 对于这个问题的解释说明
  • ¥200 询问:python实现大地主题正反算的程序设计,有偿
  • ¥15 smptlib使用465端口发送邮件失败
  • ¥200 总是报错,能帮助用python实现程序实现高斯正反算吗?有偿
  • ¥15 对于squad数据集的基于bert模型的微调
  • ¥15 为什么我运行这个网络会出现以下报错?CRNN神经网络
  • ¥20 steam下载游戏占用内存
  • ¥15 CST保存项目时失败
  • ¥20 java在应用程序里获取不到扬声器设备