Ответы пользователя по тегу Базы данных
  • Выполнение хранимой процедуры в MySQL это одна транзакция?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Нет, выполнение хранимой процедуры - не атомарная операция.
    Транзакции (BEGIN/COMMIT/ROLLBACK) в процедуре использовать можно, блокировки таблиц (LOCK TABLE) - нельзя.
    Ответ написан
    Комментировать
  • Как правильно спроектировать данную БД?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Вообще, для такой задачи есть устоявшаяся схема:

    categories (id, name) - категории (отечественный, зарубежный и т.д.)
    items (id, category_id, базовый набор атрибутов) - в вашем случае авторы
    attributes (id, name, type, ...) - возможные атрибуты
    categories_attributes (category_id, attribute_id) - атрибуты, допустимые для категории
    items_attributes (item_id, attribute_id, value) - собственно значения атрибутов

    Такая схема легко расширяется, может содержать дополнительную информацию - признак обязательности атрибута в описании, список допустимых значений атрибута для типов "один из списка", "несколько из списка", единицы измерения и т.д.
    Ответ написан
    5 комментариев
  • Как из двух таблиц в SQL сделать третью по одинаковому столбцу?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Ответ написан
    Комментировать
  • Как правильно создать SQL процедуру?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    А зачем для этого процедура? Достаточно обычного запроса
    И зачем возвращать из запроса названия организации и сервиса, если их туда только что передали?
    SELECT `os`.`service_cost`
      FROM `Org_services` AS `os`
      JOIN `Organizations` AS `o` ON `o`.`ID` = `os`.`org_id` AND `o`.`org_name` = :orgName
      JOIN `Services_list` AS `s` ON `s`.`ID` = `os`.`service_id` AND `s`.`service_name` = :servName
    Ответ написан
    9 комментариев
  • Как выбрать товары из таблицы по динамическим параметрам (находятся в другой таблице)?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Несколько JOIN'ов, каждый из которых фильтрует только один параметр.
    Ответ написан
  • Как правильно спроектировать БД?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Контакты и специализации стоит вынести в отдельные таблицы, их может быть много у одного предприятия.
    Для реализации расписания по минимуму надо таблицу с id адреса предприятия (разные точки могут иметь разное расписание), днём недели (INT), началом и окончанием работы в эти дни (TIME), началом и окончанием обеденного перерыва (TIME). Плюс аналогичную таблицу исключений, где вместо дня недели поле даты (DATE).
    Ответ написан
    5 комментариев
  • Как сделать внешний ключ уникальным, но в тоже время, чтобы он мог принимать значение NULL?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    В MySQL NULL != NULL, поэтому в колонке с индексом UNIQUE может быть любое количество NULL'ов.
    Ответ написан
    1 комментарий
  • Как правильно сделать структуру базы данных?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    В такой структуре БД поиск по группе параметров делается JOIN'ами
    SELECT *
      FROM `cars` AS `c`
      JOIN `cars_attr` AS `ca1` ON `ca1`.`id_car` = `c`.`id` 
        AND `ca1`.`id_attr` = 4 AND `ca1`.`val` >= 2004 AND `ca1`.`val` <= 2008
      JOIN `cars_attr` AS `ca2` ON `ca2`.`id_car` = `c`.`id` 
        AND `ca1`.`id_attr` = 3 AND `ca1`.`val` >= 10000 AND `ca1`.`val` <= 90000
      JOIN `cars_attr` AS `ca` ON `ca`.`id_car` = `c`.`id` 
      JOIN `attr` AS `a` ON `a`.`id` = `ca`.`id_attr`
      WHERE `c`.`category` = 1

    или через IN
    SELECT *
      FROM `cars` AS `c`
      JOIN `cars_attr` AS `ca` ON `ca`.`id_car` = `c`.`id` 
      JOIN `attr` AS `a` ON `a`.`id` = `ca`.`id_attr`
      WHERE `c`.`category` = 1
        AND `c`.`id` IN (
          SELECT `id_car` FROM `cars_attr` 
            WHERE `ca1`.`id_attr` = 4 AND `ca1`.`val` >= 2004 AND `ca1`.`val` <= 2008
        ) AND `c`.`id` IN (
          SELECT `id_car` FROM `cars_attr` 
            WHERE `ca1`.`id_attr` = 3 AND `ca1`.`val` >= 10000 AND `ca1`.`val` <= 90000
        )
    Ответ написан
    4 комментария
  • Как сделать выборку "И" и "ИЛИ" на MySQL?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Зависит от того, уникальна пара (user_id, tag_id) или нет.
    Для уникальных всё просто
    SELECT `u`.*
      FROM `users` AS `u`
      JOIN `user_tags` AS `ut` ON `ut`.`user_id` = `u`.`id`
        AND `ut`.`tag_id` IN (1, 2, ..., N)
      GROUP BY `u`.`id`
      HAVING COUNT(*) = N


    Для неуникальных добавляется DISTINCT
    SELECT `u`.*
      FROM `users` AS `u`
      JOIN `user_tags` AS `ut` ON `ut`.`user_id` = `u`.`id`
        AND `ut`.`tag_id` IN (1, 2, ..., N)
      GROUP BY `u`.`id`
      HAVING COUNT(DISTINCT `ut`.`tag_id`) = N
    Ответ написан
  • Как реализовать сортировку объектов базы данных по координатам?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    1 комментарий
  • Как отрисовывать JSON без тормозов?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Делайте серию запросов. Принимаете первый набор, с ним маркер продолжения, запрашиваете следующий, отрисовываете полученный, и так пока не получите маркер окончания.
    Ответ написан
    Комментировать
  • Как правильно построить структуру БД (SQL)?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Вариантов реализации много. Например классический способ описания:
    Таблица атрибутов (id, название, тип_атрибута, признак_обязательного)
    Варианты значений для select и multiselect (id_атрибута, номер_значения, значение)
    Таблица принадлежности атрибутов (тип_документа, id_атрибута)
    Таблица значений атрибутов (id_документа, id_атрибута, значение)

    А валидацией должен заниматься клиент, в самой БД для этого нет средств.
    Ответ написан
    Комментировать
  • Нужно ли защищать данные в зависимых таблицах с помощью Foreign Key?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Это только вы можете решить, нужно ли вам сохранять ссылочную целостность базы.
    Ответ написан
    Комментировать
  • Как работают агрегатные функции?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    В стандарте при использовании агрегатных функций каждое поле выборки, ORDER BY и HAVING должно быть либо результатом агрегатной функции, либо входить в GROUP BY. Таким образом приведённый вами запрос в стандарте недопустим.
    MySQL, до последней версии, допускал нестандартное использование агрегирования, выбирая для неагрегированых полей первое попавшееся значение. Начиная с версии 5.7 MySQL начал требовать соблюдения стандарта, и приведённый вами запрос выдаст ошибку. Вернуться к старым настройкам можно отключив режим ONLY_FULL_GROUP_BY в настройках или явно используя агрегатную функцию ANY_VALUE() на полях, которые раньше не агрегировались. Ваш запрос в этом случае будет выглядеть как
    SELECT ANY_VALUE(`id`), ANY_VALUE(`name`), ANY_VALUE(`age`), COUNT(*) 
      FROM `student`;

    Поскольку в запросе не указано, по каким полям проводить группировку, MySQL группирует все строки в одну. Если использовать GROUP BY <список полей>, то будут группироваться строки с одинаковыми значениями указанных в списке полей. Так запрос
    SELECT `age`, COUNT(*) 
      FROM `student`
      GROUP BY `age`;

    выдаст
    +------+----------+
    | age  | COUNT(*) |
    +------+----------+
    |  18  |    2     |
    |  17  |    1     |
    | NULL |    1     |
    +------+----------+
    Ответ написан
    Комментировать
  • Нужно ли таблицу users разделять на несколько?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    А какая разница, сколько там столбцов, если они реально необходимы? Запрашивайте только нужные и всё.
    Ответ написан
    5 комментариев
  • Когда нужно думать о создании базы данных?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Если приложение однопользовательское и никакого поиска по данным не надо - база данных не нужна.
    Если у вас сайт, рассчитанный на одновременную работу более, чем одного человека, то без базы данных не обойтись. Простейшее изменение данных, выполняемое на БД одной атомарной командой, в случае файлов потребует блокировки файла, а значит ожидания его освобождения остальными пользователями.

    P.S.
    Ок, пусть будет блог. Комментировать посты в нём можно будет? Тогда надо как-то эти комментарии записывать. Лайки ставить или карму править - это тоже запись данных. Даже простейший счётчик просмотров это уже изменение данных. Вот на примере такого счётчика обычно и поясняют необходимость атомарности и блокировок. Представьте, что два человека одновременно открыли пост блога и скрипты увеличивают счётчики прочтения, старое значение 99.

    Скрипт 1: прочитать файл "счётчики"
    Скрипт 2: прочитать файл "счётчики"
    Скрипт 1: найти в файле счётчик поста, получили 99
    Скрипт 2: найти в файле счётчик поста, получили 99
    Скрипт 1: увеличить счётчик поста, получили 100
    Скрипт 2: увеличить счётчик поста, получили 100
    Скрипт 1: записать файл "счётчики"
    Скрипт 2: записать файл "счётчики"

    То есть вместо ожидаемых 101 в счётчике всего 100. Значит перед изменением любых данных необходимо заблокировать файл на запись, считать из него актуальные данные, внести изменения, записать файл, разблокировать его. Ну а поскольку это json, то считывать и записывать файл каждый раз придётся целиком. Если при изменении данных меняется связь с данными в других файлах, то во избежание нарушения целостности блокировать придётся все связанные файлы.

    Ну и поиск по данным, скажем десять самых читаемых постов. В файловом варианте вам придётся считать весь json, и отсортировать его, тогда как в БД при правильной расстановке индексов это действие выполняется в один запрос с линейным получением первых десяти записей по индексу.
    Ответ написан
    5 комментариев
  • Проблемы с sql_mode=ONLY_FULL_GROUP_BY?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    В режиме ONLY_FULL_GROUP_BY все получаемые в запросе данные должны быть в агрегатных функциях (SUM, COUNT, MAX, и т.д.) или по ним должна проводиться группировка. В вашем запросе `idate` не входит ни туда, ни туда, поэтому MySQL в строгом режиме не знает, из какой именно строки таблицы взять значение.
    Либо убирайте колонку `idate` из запроса, либо включайте её в агрегатную функцию.
    Можете отключить ONLY_FULL_GROUP_BY, тогда `idate` будет браться, как правило, из первой строки, попавшей в группировку.
    Ответ написан
  • Как можно удалить старые записи, оставив, как минимум, одну последнюю для каждого датчика?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    DELETE `t1`
      FROM `channel_snapshots` AS `t1`
      LEFT JOIN (
        SELECT MAX(`snapshot_time`) AS `time`, `channel_id`
          FROM `channel_snapshots`
          GROUP BY `channel_id`
      ) AS `t2` ON `t2`.`time` = `t1`.`snapshot_time` AND `t2`.`channel_id` = `t1`.`channel_id`
      WHERE `t1`.`snapshot_time` < NOW() - INTERVAL 12 HOUR 
        AND `t2`.`channel_id` IS NULL
    Ответ написан
    1 комментарий
  • Как автоматически удалять запись из бд через 10 минут?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Вариант 1 - ставить время бронирования, запускать крон раз в минуту, удалять все неподтверждённые бронирования старше 10 минут.
    Вариант 2 - запустить шедулер MySQL и вместе с бронированием создавать событие на его удаление при отсутствии подтверждения.
    Ответ написан
    1 комментарий
  • Связь многие ко многим в MS SQL для чего?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Простейший пример - сотрудники и группы. Сотрудник может входить в несколько групп, в группу может входить несколько сотрудников.
    Ответ написан
    Комментировать