O que é a forma mais eficiente de organizar essas tabelas + linhas?- MySQL
-
12-12-2019 - |
Pergunta
Eu estou indo para ser executado loterias no meu site, e portanto, não precisa ser um lugar para armazenar os bilhetes e números.Com certeza vou ter uma tabela, chamada de tickets
em que cada linha terá o seu próprio bilhete de id, os seus associados loteria id e todas as outras informações (como o id do usuário a quem pertence).
No entanto, a minha pergunta é se devo fazer um outro campo em tickets
para manter os números escolhidos no bilhete.Não é uma opção para criar vários campos, tais como number1
, number2
etc, como cada loteria terá diferentes tipos de bilhetes (que eu.e lottery1
pode pedir-lhe para escolher 4 números, e lottery2
pode pedir-lhe para escolher 6).
Então eu posso fazer um novo campo que é VARCHAR ou TEXT para aceitar separados por vírgula, número do bilhete, eu.e: 1,2,3,4,5,6
ou fazer outra nova tabela chamada numbers
onde cada linha teria o bilhete de identificação e o número associado a ele.No entanto eu não sei se este método é muito eficiente, como, por apenas um bilhete de 6 números, não precisaria ser de 1 linha no tickets
mesa e 6 linhas na numbers
tabela.
Qual dessas opções é a mais eficiente?Ou será que há uma maneira melhor de fazer isso do que este?Por favor, lembre-se que no final da lotaria, o código será necessário para percorrer cada um bilhete para verificar se eles ganharam - então a opção 2 não pode ser demasiado de recursos sedentas de lá.
Solução
Na seguinte, "Bilhete[Número]" deve ser tomado para significar "Selecionado Conjunto de Números de Loteria".Lembre-se de que Set(a,b,c)
é igual a Set(c,b,a)
.
Eu gostaria que fosse assim:
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
Que é, Purchase:M-1:Ticket
O DisplayTicketNumber
é o número que o usuário selecionado, e.g."3,1,2", enquanto, por outro lado, o TicketNumber
é normalizada e número de bilhete onde os pequenos valores são colocados em primeiro lugar.A forma final é, portanto, min,..,max
ou semelhante.Que é, com qualquer número de DisplayTicketNumbers
que têm o mesmo conjunto de valores (em qualquer ordem) terá o mesmo 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
Em seguida, colocar um índice em TicketNumber
então, o que um simples WHERE TicketNumber = @normalizedTicketNumber
vai ser muito rápido de índice.
Eu seria, na verdade, argumentam que esta é uma aceitável normalizado o design e a TicketNumber (juntamente com o Sorteio de número) formulários de uma Chave.Meus argumentos para isso são assim:
Um TicketNumber é um valor opaco que identifica de forma única um Bilhete (por Sorteio).Não é preciso "conhecer os detalhes" dentro do DB modelo.(Poderá ser necessário, em alguns casos, mas não aqui.)
O DisplayTicketNumber é um artefato de entrada de utilizadores;ainda assim, vários DisplayTicketNumbers podem representar o mesmo TicketNumber.Enquanto isso não representam possíveis "duplicação" é importante perceber que este é um Amigável valor que representa um lista (que tem mais informações do que um conjunto) de números escolhidos.
Em um caso como esse, eu gostaria de fazer o
DisplayTicketNumber
(eTicketNumber
) imutável com disparadores de modo que, após a criação, o banco de dados, inconsistências podem ser apresentados aqui.Se um FK pode ser calculado, em seguida, a restrição entre DisplayTicketNumber e TicketNumber pode ser executada sem que a imutabilidade.
(Eu tenho omitido vários detalhes como ter diferentes TicketNumbers para diferentes Sorteios, etc.Eu também mostrar um TicketId
para um FK, mas eu também deu a entender que RaffleId,TicketNumber
é aceitável [não-substituto] Chave.)
Além disso, o Bilhete tabela poderia ser eliminado:uma vez que muito poucas Loteria Número de Conjuntos serão compartilhados de modo que, se não há nenhum extra associado Bilhete de informações e, em seguida, removê-la pode ser um aceitável denormalization.Uma vantagem deste é, em seguida, o TicketNumber
poderia ser movido para o Purchase
tabela e, em seguida, se transformou em um coluna calculada (o que é indexada) que normalizado o valor do Bilhete.
E, se O MySQL permite o uso de uma coluna computada em um FK, em seguida, usando a relação PK(Ticket.TicketNumber)
-> FK(Purchase.TicketNumber)
, onde Purchase.TicketNumber
é calculado, poderia ser usados para aumentar a integridade do modelo, sem eliminar o Bilhete de tabela.(Eu não uso o MySQL, no entanto, então não posso dizer se é viável ou não.)
Codificação feliz.
Outras dicas
- Vou usar a segunda opção, onde você faz a nova tabela, chamada de números, e você terá o número associado a ele.
Mas eu também adicionar um campo na bilhetes de tabela, onde você indica a quantidade de números que podem ser selecionados, e uma condição em que você verifique se a quantidade de números inseridos usando esse bilhete (usando a CONTAGEM em uma consulta) é menor que a quantidade de números que podem ser seleccionadas e, em seguida, inserir.