Ответы пользователя по тегу MySQL
  • Как спроектировать покупку абонемента?

    valerium
    @valerium
    Изобретая велосипед
    На мой взгляд, лучше организовать схему хранения так.

    В таблице с клиентами есть поле abonement_expiration, в котором хранится дата истечения абонемента. При регистрации туда пишется дата регистрации и проверка абонемента проводится сравнением с текущей датой. Кроме того, здесь же содержится ссылка на реферера.
    CLIENT (
        id_client,
        name,
        email,
        abonement_expiration,
        referer )


    Таблица со списком заказов. Нужна в первую очередь для бухгалтерии, история заказов и всё такое.
    ORDER (
        id_order,
        id_abonament,
        id_client,
        amount,
        status,
        date_order)


    Покупка абонемента оформляется транзакцией, которая состоит из (лень писать код :-)
    1. занесения заказа в таблицу с заказами,
    2. извлечения текущей даты истечения из таблицы с клиентами,
    3. подсчёта новой даты с учётом стоимости абонемента,
    4. занесения новой даты истечения в таблицу с клиентами.

    Операции 2-4 можно оформит одним запросом, но всё четыре в любом случае должны быть одной транзакцией.

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

    Организация реферальной программы - дело не хитрое. Дополнительное поле в таблице с пользователями позволяет без труда найти реферера и рефералов. Идея с куками, которую предложил Максим Кудрявцев - отличное решение, лучше не придумаешь.
    Ответ написан
    Комментировать
  • Занесение данных из файла .xml в MySQL?

    valerium
    @valerium
    Изобретая велосипед
    Учитывая, что именно по статусу Вы будете искать очень часто, то имеет смысл их вынести в отдельную таблицу, чтобы поиск по основной таблице был по целому числу.

    Да, поиск дубликатов будет занимать немного лишнего времени, но если есть индекс, заминка будет незаметной.
    Ответ написан
  • Какой запрос составить для выборки изображений из базы по заданым фильтрам?

    valerium
    @valerium
    Изобретая велосипед
    По сути, что цвет, что ключевое слово - это всё тэги, то есть вполне уместно использовать связь многие-ко-многим. То есть отдельная таблица с изображениями, отдельная таблица с цветами, отдельная с ключевыми словами. И две таблицы для связей, одна связывает цвета с изображениями, другая ключевые слова с изображениями. Таким образом можно делать очень сложные выборки.

    SELECT * FROM `images` WHERE
        `images`.`id` = `keyword-to-image`.`image_id` AND
        `images`.`id` = `colors-to-image`.`image_id` AND
        `keyword-to-image`.`keyword_id` = 234 AND
        `colors-to-image`.`color_id` = 345 AND
        `colors-to-image`.`color_id` <> 543;


    То есть мы получим все изображения, к которым привязано ключевое слово с id 234 и цвет с id 345, но при этом не привязан цвет с id 543. Количество этих AND можно легко менять в скрипте. Кроме того, сравнение целых чисел намного быстрее сравнения строк.

    Правда, это потребует перестройки всей базы данных, но только один раз, достаточно написать скрипт.
    Ответ написан
    1 комментарий
  • Как оптимизировать sql запрос?

    valerium
    @valerium
    Изобретая велосипед
    Напишите триггер, который при вставке будет будет текущий weight вставлять в таблицу типа Memory. Соответственно, оттуда же вставка его будет брать. Правда, при этом потребуется однократная "инициализация" при запуске БД.

    Можно триггером и в простую MyISAM таблицу писать, это будет чуть дольше, зато без проблем с перезагрузкой.

    И да, поясните, зачем оно вообще надо. Любопытно :-)
    Ответ написан
    4 комментария
  • Как правильно ввести склад и финансы (бизнес-логика)?

    valerium
    @valerium
    Изобретая велосипед
    Насколько знаю, обычно интернет-магазины хранят баланс клиента в виде поля в таблице с данными клиентов. При пополнении баланса или при покупке это поле перезаписывается. И я не вижу причин от этой практики отказываться.

    У Вас стоит задача (насколько я понял) видеть баланс нескольких пользователей в реальном времени (запрашивать его раз в несколько секунд). Мне сложно представить более быстрый метод, чем считывание переменной из оперативной памяти (таблица БД в опер. памяти или Memcached). Хорошо настроенная СУБД может с сопоставимой скоростью извлечь эти данные и с жёсткого диска.

    Учитывая запланированную оптимизацию под большие нагрузки, я бы предложил соорудить очередь заказов. Первый пришёл — первый ушёл. Взяли из очереди заказ, переписали переменную с балансом пользователя, взяли следующий заказ. Таким образом подстреливаем двух зайцев: 1) имеем быстрый доступ к балансу пользователя, 2) точно знаем нагрузку на систему (время ожидания в очереди) и заранее добавляем новых исполнителей.

    Что касается пересчёт баланса, то Вы, судя по всему, уже всё продумали. Исправляем ошибочную запись, останавливаем обработку очереди, пересчитываем баланс от любой контрольной точки. Контрольные точки записываются по расписанию, так же с остановкой очереди. Частоту записи КТ нужно определять уже на месте, исходя из потребностей системы.
    Ответ написан