Ответы пользователя по тегу MySQL
  • Полиморфизм в базе данных, как организовать таблицы?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Разделяйте ответственности
    OrganisationSeller и PersonSeller могут наследоваться от Seller
    и для реализации такого можно реализовать такой паттерн Single Table Inheritance

    А вот обычные Organisation и Person связывайте с абстрактным Seller через обычную связь. Конкретные наследники будут лежать в зависимости от типа

    Итого будет так:
    (OrganisationSeller extends Seller) будет объектом Organisation.seller

    Готовые решения:
    Ответ написан
  • Как обнулить или объединить миграции и оставить одну?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Боевая БД
    Нужно понимать, что боевая БД уже не будет накатываться с первой миграции. Миграции старше последней (или нескольких последних миграций, куда еще есть шанс откатиться) на боевой БД проделываться не будут, боевой базе достанутся только будущие миграции. Потому дамп делать никакой не нужно (ну спец под эту операцию, эта операция не связан с боевой БД никак) — дальше прилетят только новые изменения.

    На машине разработчика
    Если все сделано аккуратно (когда работали с миграциями), то можно удалить все таблицы и попробовать сгенерировать diff — он сделает актуальную миграцию, которая необходима. Далее нужно удостовериться — не было ли придуманных вне ORM миграций и таблиц, крч сверить с боевой схемой. Также возможно миграции несли некоторые данные (ну например коды валют, которых всего 5-10 вы решили миграцией занести или пара дефолтных значений из таблицы settings, и подобные случаи) — нужно будет руками это повторить (или не повторять, если не нужно).
    Если вы добились, что ПУСТОЙ БД накаткой миграций получается ровно то, что достигалось ранее, то:
    • вы спокойно можете удалить старые миграции и коммитить эту одну большую
    • перед выкаткой на прод — вы должны текущую миграцию занести в таблицу migration_versions руками


    Done!

    Все делается очень легко, мне как-то достался проект без доступа к старому GIT (и почему-то без миграций), но с боевой БД. Пришлось проделать приблизительно все тоже самое (не считая болевого обновления Symfony с 2.7 до 3.4 с Сонатой, было больно :):):))...
    Все проделывания с миграциями заняли от силы полтора часа (в виду молодости и не опытности), было пару подводных моментов (типа у некоторых бандлов из vendor были свои папки со своими мииграциями) и данные нужны были. некоторые, а так все относительно легко
    Ответ написан
  • Как правильно строить таблицу с товарами, на примере?

    Maksclub
    @Maksclub
    maksfedorov.ru
    1 вопрос. Но к примеру как быть с ценой товара, или с количеством товара? Вроде как можно писать в таблицу товара?

    Обычно делают варианты (часто можно встретить офферы, SKU), а товар -- лишь общая информация (название, описание, страна, бренд, урл, картинка и прочее -- в общем случае). Варианты они могут иметь и размер и цвет и они конечно и содержат и цену и количество:

    Джинсы Левис (синие, мужские, Levis, 2019 года и прочее):
       - S (6 500 рублей, 10 штук)
       - L (6 500 рублей, 1 штука)
       - XXXL (6 500 рублей, 2 штуки)

    Отношения -- один ко многим

    То есть есть таблица товаров, есть таблица вариантов (размеров, цветов, офферов), есть таблица значений характеристик и есть таблица названий характеристик
    Ответ написан
  • Как снизить нагрузку на БД или какую БД использовать?

    Maksclub
    @Maksclub
    maksfedorov.ru
    В порядке действий:
    • анализ, что работает медленно (не "заказчик говорит медленно", а например "запрос для товаров, при выборке по акциям и покупателям" работает 2 секунды)
    • оптимизация кода, работающего с запросами (снижение числа запросов или более точные выборки) -- самая популярная проблема,

      - снижал на этом только этапе в 1000-1500 раз,
      - видел по 1500 запросов на страницу,
      - видел 1 запрос, но на всю таблицу и потом по коду с этими данными гигантская работа, когда можно было сделать 2 ооочень шустрых запроса в БД с конечными данными :)
      - запросы в цикле, очень много раз видел (гуглить проблема N+1)


    • оптимизация медленных запросов

      Сделать запрос более быстрым, за счет или более точных выборок, или более верного синтаксиса, или стоит например раздробить на нексколько очень мелких, а бекендом все привести к нужному виду

    • индексы (сильно оптимизируют и бывают достаточны для решений многих бед со скоростью на большой выборке)
    • кеш на стороне БД
    • кеш на стороне приложения
    • денормализация некоторых данных, например предагрегация (например меню сайта и нужно для каждого вывести число твоаров, каждый пункт связан с категорией, категорий много, чтобы каждый раз по 100 категорий на подсчет товаров для каждой не делать -- делать это сильно реже и хранить в некой агрегирующей табличке)

    С техниками типа шардинга/репликации никогда не работал
    Ответ написан
  • Как ускорить join paginate с подзапросом?

    Maksclub
    @Maksclub
    maksfedorov.ru
    SELECT o.*, w.priority
    FROM orders o
    LEFT JOIN (
            SELECT order_id, max(priority) as priority
            FROM waypoints
            GROUP BY order_id
    ) w ON o.id= w.order_id
    ORDER BY w.priority desc


    то есть получаем табличку в виде заказ:максимальный_приоритет
    и полученную таблицу джойним с заказами, сортируя по полученному приоритету
    Ответ написан
  • Как вы именуете таблицы связей?

    Maksclub
    @Maksclub
    maksfedorov.ru

    accounts
    awards

    Я по отношениям называю:
    • Многие ко многим: accounts_awards
    • Один ко многим: или account_awards или accounts_award по конкретной ситуации

    (это особенно полезно, когда таблиц 100+)

    Работаю в Шторме с БД, потому просто набираю буквами нужное имя и мне быстро выдается что нужно без заморочек с предлогами
    Ответ написан
  • Как получить все посты, которые не комментировал определенный пользователь?

    Maksclub
    @Maksclub
    maksfedorov.ru
    SELECT c.id, c.text, u.id as user, p.id as post
    FROM comments c
    LEFT JOIN users u ON u.id=c.user_id
    LEFT JOIN posts p ON p.id=c.post_id
    WHERE u.id != 235

    Уточнения:
    • 235 — id пользователя
    • таблицу users приджойнил, тк обычно нужна инфа и по пользователю

    Использование listView
    https://github.com/yiisoft/yii2/blob/master/docs/g...
    Ответ написан
  • Реальные простые и понятные примеры Join в mysql?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Например у товара могут быть варианты (размеры или цвет)

    Таблица товаров products:
    id, name
    1, IPhone
    2, Macbook

    Таблица вариантов variants:
    product_id, name, price
    1, Черный 64Gb, 20000
    1, Белый 32Gb, 10000
    2, 15 дюймов, 100000


    Выбрать все варианы для товара с id=1 будет так:
    SELECT v.name, v.price
    FROM variants v
    LEFT JOIN products p ON p.id=v.product_id
    WHERE p.id=1


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

    Maksclub
    @Maksclub
    maksfedorov.ru
    Создается таблица purchases (покупки) с полями:
    • order_id — несколько записей выбираеются по этому полю, и у вас будет актуальное количество и значения товаров
    • amount — количество товара в заказе
    • product_id — привязка к товару, например получить его фото, но оно не обязательное, тк из основной таблицы может исчезнуть товар (сняли, удалили, распродали, мало ли что...), потому нужо завести поля name, price, sku, offer (или variant) и прочее

    Готовый пример (product_id пустой, тк нет товара, но в истории заказа всегда есть инфа):
    5a91daa9ba0d0598154064.png
    Ответ написан
  • Как правильно хранить сопутствующие товары?

    Maksclub
    @Maksclub
    maksfedorov.ru
    можно через связи -- таблица related_products (product_id, related_product_id)
    product_id, related_product_id
    1, 4
    1, 34
    1, 45
    1, 6


    Для первого товара выбрать id привязанных к продукту 1:
    SELECT id, name
    FROM products
    WHERE id IN (SELECT related_product_id FROM related_products WHERE product_id=1 )
    Ответ написан
  • Для чего может быть нужен sequence?

    Maksclub
    @Maksclub Автор вопроса
    maksfedorov.ru
    Добавлю к LS Timer
    Sequence используют для того, чтобы ДО INSERT мы могли работать с полноценной сущностью, у которой уже до добавления есть свой необходимый ID
    Ответ написан
  • Почему pdo драйвер возвращает int как string?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    На уровне PDO

    'options'   => array(
                PDO::ATTR_STRINGIFY_FETCHES => false,
                PDO::ATTR_EMULATE_PREPARES => false,
    Ответ написан
  • Как пренести товар с drupal на opencart?

    Maksclub
    @Maksclub
    maksfedorov.ru
    возможно,
    как именно сделать — сложно понять, тк разные у вас структуры БД

    как варианты:
    • найти способ импорта в опенкарт из csv, посмотреть формат этого csv и под этот формат сделать выгрузку из друпала
    • попробоать на пярмую организовать передачу данныз из одной БД в другую... тут нужен опыт прогарммирования
    • простой способ — спарсить товары с друпала, как-будто это и не ваш сайт... спарсить например в все тот же формат csv и импортировать полученное в опенкарт
    + еще десяток способов
    Ответ написан
  • Mysql для email маркетолога - какие функции необходимо знать?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Лучше всего заранее спроектировать основные сценарии для запроса данных и попросить техспецов сделать форму с доступом по паролю, в котором можете с выпадающими списками и чекбоксами делать выборку того, что нужно, а получив нужные данные по кнопке "Скачать" их скачать.

    Если прижало:
    1. Понять принципы реляционных баз (построение базы на основе отношений),
    тут сейчас есть один главный принцип — 3 нормальная форма, почитать:

    2. Заведомо получить инструмент для доступа к БД и отдельно научиться подключатсья к ней

    3. Научиться делать запросы с SELECT, то есть только чтение:
    • делать запросы из 1 таблицы с разными условиями
    • делать запросы из 2 и более таблиц с отношениями с условиями, например выбрать всех пользователей с именем Андрей и данные для этих пользователй в др таблицы заказов

    Поупражняться: sql-ex.ru/learn_exercises.php

    4. Чтобы сохранить:
    • научиться выгружать в файл ,чтобы его можно было скачать для последующего использования
    • найти конвертер дял перегона SQL результата в csv, вот нашел такой: www.convertcsv.com/sql-to-csv.htm, но может есть лучше
    • или научиться программировать, если у вас аналитика — посмотрите в сторону языка Python
    Ответ написан
  • Как создать миграцию таблицы на основе другой таблицы?

    Maksclub
    @Maksclub
    maksfedorov.ru
    ВАРИАНТЫ:
    1. Уже предлагали: Как синхронизировать только структуру БД?
    2. Разово написать запрос ALTER руками
    3. Использовать миграции
      - в первой миграции делать загрузку дампа со структурой существующей Foo через файл, который будет лежать например с миграциями
      - руками описать миграции, обновляющие таблицу
      - и далее работать как белые люди



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

    Maksclub
    @Maksclub
    maksfedorov.ru
    Вам нужно разделить данные на несколько таблиц, согласно 3 нормальной формы (изучите отдельно)

    • Города (поселки) — отдельная таблица
    • Участки — отдельная таблица
    • Жители — отдельная таблица

    Связи 1 к 1 тут в основном (хотя житель может гипотетически жить в нескольких участках)

    Совсем недавно на похожую тему давал советы, там совсем др тематика,
    но попробуйте вникнуться:
    Делать 1 большую таблицу или разбивать на части?
    Какие таблицы БД должны быть в таком онлайн справочнике(ссылка внутри)?
    Ответ написан
  • Делать 1 большую таблицу или разбивать на части?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Чтобы не громоздить тонны колонок и делать по канонам 3 нормальной формы — разделяют сущности, атрибуты и их значения отдельно.

    Свойства обычно хранят отдельно( у них могут быть свои поля)
    5a68a3b0baf0c785050166.png
    а значения к ним тоже отдельно (EAV)
    product_id, feature_id, value (где featured_id — id свойства из таблички выше)

    пример с моего интернет-магазина — 1 товар, много характеристик
    5a68a6c2b19f2067082314.png

    Пример запроса:
    SELECT   p.id, p.url, p.name
    FROM e_products p		
    WHERE 1 
    AND p.id in (SELECT product_id FROM e_options WHERE feature_id=8 AND value in('Бежевый','Белый') )
    AND p.id in (SELECT product_id FROM e_options WHERE feature_id=1 AND value in('Лето 2011') )
    время выполнения запроса — 0.019 s для 10 тыс товаров, 100тыс значений свойств и десятка свойств

    В запросе два параметра фильтра (1 значение коллекции и 2 значений цвета, выше можете увидеть в табличке)
    как понимаете — строку с нужным свойством подставляете в зависимости от GET запроса...

    * Можно упростить — вместо feature_id хранить сразу название параметра, но лучше сразу разделите... чтобы можно было параметру поставить напрмиер поле включать или нет его в фильтр и задать порядок, или нужно будет выводить поля в саму форму фильтра (гонять большую таблицу — так себе решение)
    Ответ написан
  • Как сделать выборку из трех таблиц одной БД?

    Maksclub
    @Maksclub
    maksfedorov.ru
    SELECT hosting.user_id, client.name, client.email, client.phonenumber, product.packagename
    
    FROM tblhosting hosting
    LEFT JOIN tblclients client ON client.id=hosting.user_id
    LEFT JOIN tblproducts product ON product.id= hosting.packageid
    
    WHERE hosting.domainstatus = 'Terminated'
    AND hosting.packageid IN ('1' , '2' , '3')


    А насчет логики работы JOIN мне пока не понятно, все запросы, которые я пытался сделать - вообще не работали.
    Пишите сначала один селект, потом присоединяете таблицу, потом в выборку добавляете данные с новой таблице и так по чуть-чуть усложняете запрос....
    Ответ написан
  • Хранение и вывод городов из БД Mysql методом closure table?

    Maksclub
    @Maksclub
    maksfedorov.ru
    делайте как вам в прошлом вопросе посоветовали

    сделайте таблицы:
    • s_regions
    • s_regions_path

    s_regions
    +-----------------------------+
    |  id   |         name        |  
    +-----------------------------+
    |   1   |         Россия      |
    +-----------------------------+
    |   2   |  Московская область |
    +-----------------------------+
    |   3   |        Москва       |
    +-----------------------------+


    Я мог немного напутать с полем level, так как только вчера сам узнал о таком алгоритме и не реализовываал его еще
    s_regions_path
    +-----------------------------------+
    | region_id |  path_id  |   level   |
    +-----------------------------------+
    |      2      |      1    |    1    |   <-- Тут мы храним связь Мособласти, указываем связь с Россией
    +-----------------------------------+
    |      3      |      2    |    1    |   <-- Тут мы храним связь  Москвы указывая на Мособласть
    +-----------------------------------+
    |      3      |      1    |    2    |   <-- Тут мы храним связь Москвы с Россией
    +-----------------------------------+


    Достать всех детей России (id=1):
    SELECT r.id, r.name
    FROM s_regions r
    LEFT JOIN s_regions_path l ON l.region_id=r.id
    WHERE l.path_id=1


    Достать только города Мособласти (id=2), то есть только следующий уровень (не уходя глубже):
    SELECT r.id, r.name
    FROM s_regions r
    LEFT JOIN s_regions_path l ON l.region_id=r.id
    WHERE l.path_id=2
    AND l.level=1


    Получить все зависимости для Москвы (id=3) и отсортировать по возрастанию уровня:
    SELECT r.id, r.name
    FROM s_regions r
    LEFT JOIN s_regions_path l ON l.region_id=r.id
    WHERE l.region_id =3
    ORDER BY l.level DESC
    Ответ написан