Как наиболее эффективно организовать эти таблицы + строки?- MySQL

StackOverflow https://stackoverflow.com//questions/11679778

Вопрос

Я собираюсь проводить лотереи на своем веб-сайте, поэтому нужно где-то хранить билеты и номера.У меня обязательно будет столик под названием tickets в котором каждая строка будет иметь свой собственный идентификатор билета, связанный с ним идентификатор лотереи и всю другую информацию (например, идентификатор пользователя, которому он принадлежит).

Однако мой вопрос в том, стоит ли мне создавать еще одно поле в tickets для хранения номеров, выбранных в билете.Невозможно создать несколько полей, таких как number1, number2 и т. д., поскольку в каждой лотерее будут разные типы билетов (т. е. lottery1 может попросить вас выбрать 4 номера, и lottery2 может попросить вас выбрать 6).

Поэтому я могу создать новое поле VARCHAR или TEXT для приема номеров билетов, разделенных запятыми, т. е.: 1,2,3,4,5,6 или создайте еще одну новую таблицу под названием numbers где каждая строка будет иметь идентификатор билета и номер, связанный с ним.Однако я не уверен, что этот метод очень эффективен, поскольку для одного билета из 6 номеров должна быть 1 строка в tickets таблице и 6 строк в numbers стол.

Какой из этих вариантов наиболее эффективен?Или есть еще лучший способ сделать это, чем этот?Помните, что в конце лотереи код должен будет циклически просмотреть каждый билет, чтобы проверить, выиграли ли они, поэтому вариант 2 может оказаться слишком ресурсоемким.

Это было полезно?

Решение

В дальнейшем «Билет[Номер]» следует понимать как «Выбранный Набор лотерейных номеров».Помните, что 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 будет очень быстрый индекс.

Я бы даже сказал, что это приемлемо нормализованный дизайн, а номер билета (вместе, скажем, с номером лотереи) образует ключ.Мои аргументы в пользу этого таковы:

  1. TicketNumber — это непрозрачное значение который однозначно идентифицирует Билет (для каждого Розыгрыша).Не нужно «знать детали» внутри модели БД.(В некоторых случаях может возникнуть необходимость, но не здесь.)

  2. DisplayTicketNumber — это артефакт, введенный пользователем;однако несколько DisplayTicketNumbers могут представлять один и тот же TicketNumber.Хотя это делает представляют собой возможное «дублирование», важно понимать, что это Дружественный дисплей значение, которое представляет собой список (который содержит больше информации, чем набор) выбранных чисел.

    1. В таком случае я бы сделал DisplayTicketNumberTicketNumber) неизменяем с триггерами, так что после создания сюда не могут быть внесены несоответствия базы данных.

    2. Если FK может быть вычислен, то ограничение между DisplayTicketNumber и TicketNumber может быть реализовано без неизменяемости.

(Я опустил некоторые детали, например наличие разных номеров билетов для разных розыгрышей и т. д.Я также показываю TicketId за ФК, но я еще и намекнул, что RaffleId,TicketNumber является приемлемым [несуррогатным] ключом.)

Также таблица билетов мог быть устранены:поскольку очень немногие наборы номеров лотереи будут общими, поэтому, если нет дополнительной связанной информации о билете, ее удаление может быть приемлемый денормализация.Одним из преимуществ этого является то, что TicketNumber можно было бы переместить в Purchase стол, а затем превратился в вычисляемый столбец (который все еще индексируется), который нормализовал стоимость билета.

И, если MySQL позволяет использовать вычисляемый столбец в FK, а затем использовать отношение PK(Ticket.TicketNumber) -> FK(Purchase.TicketNumber), где Purchase.TicketNumber вычисляется, мог использоваться для повышения целостности модели без устранения таблицы Ticket.(Однако я не использую MySQL, поэтому не могу сказать, жизнеспособно это или нет.)

Приятного кодирования.

Другие советы

Я бы использовал второй вариант, когда вы создаете новую таблицу, называемую числами, и с ней связаны числа.

Но я бы также добавил поле в таблицу билетов, где вы указываете количество номеров, которые можно выбрать, и условие, в котором вы проверяете, меньше ли количество номеров, вставленных с помощью этого билета (используя COUNT в запросе), количество чисел, которые можно выбрать, а затем вставить.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top