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

    @bobzer
    Java EE Developer
    Уже год мой софт работает в облаке. Взял Windows (да, я люблю графические интерфейсы и не знаю Linux) с 1ГБ памяти и динамически выделяемым процессором (от 800 до 2300 МГц). На одном виртуальном сервере стоит и СУБД MySQL и Tomcat с моим приложением. Большую часть времени сервер потребляет минимальную планку процессора (800 МГц), потребление памяти 98% времени не боле 800 МБ, обычно 600-700 МБ. Была нагрузка до 20 запросов в секунду, мощности хватило на то, чтобы работать стабильно, без подвисаний (и это все под Windows!). Сделайте так же, один-в-один, одного сервера может хватить надолго. Современные облака выделяют дополнительные ресурсы автоматически, не превышая указанного вами предела (предел нужен чтобы не разориться если вдруг что...), так что неожиданной нагрузки можно не бояться.
    Ответ написан
    Комментировать
  • Hibernate many to many с дополнительными атрибутами?

    @bobzer
    Java EE Developer
    Думаю, что вам нужен one-to-many на самом деле, т.е. в сущности User хранится список сущностей Achievement. При этом сущность Achievement имеет поля, описывающие конкретное достижение конкретного пользователя (дата получения и другие параметры), а также ссылку на тип достижения (следующий уровень one-to-many). По поводу Set/List - как объявите в классе так и будет, но для сортировки требуется указать order-by в .hbm.xml.

    Примерно так:
    public class User {
        private List<Achievement> achievements;
        get...
        set...
    }
    
    public class Achievement {
        private User user;
        private Date createDate;
        private DicAchievementType type;//справочник типов достижений
        get...
        set...
    }


    User.hbm.xml
    <bag name="achievements" inverse="true" cascade="all,delete-orphan" order-by="CREATE_DATE">
        <key column="user_id"/>
        <one-to-many class="Achievement"/>
    </bag>


    Achievement.hbm.xml
    <many-to-one name="user" column="user_id" class="User"/>
    <many-to-one name="type" column="achievement_type_id" class="DicAchievementType"/>
    Ответ написан
    1 комментарий
  • Как заблокировать таблицу в SQL?

    @bobzer
    Java EE Developer
    когда первая копия create_task считала данные,создала поток но еще не изменила статус записи, а вторая копия уже считала данные
    Лично я уже много лет в таких случаях использую конструкцию SELECT ... FOR UPDATE - т.е. считывание с одновременной блокировкой, которое осуществляется в пределах открытой транзакции. Первый поток считывает запись и блокирует ее на уровне СУБД. При этом любой другой поток(и), попытавшийся считать запись также с модификатором FOR UPDATE будет ожидать своей очереди до тех пор, пока первый не завершит транзакцию (изменив при этом статус обработки). Только после этого следующий поток продолжит исполнение, и завершит операцию чтения. При этом надо не забыть проверить статус - если после захвата блокировки мы видим, что статус "обработано", то текущий поток "опоздал" и должен завершиться без дальнейшей обработки записи.
    Ответ написан
    Комментировать
  • SQL запрос из 3 таблиц по 2-м связующим - возможно ли такое?

    @bobzer
    Java EE Developer
    Добавлю немного магии к ответу AMar4enko:

    SELECT books.title,
    GROUP_CONCAT(distinct CONCAT(authors.surname, ' ', authors.name) SEPARATOR ', ') as autors,
    GROUP_CONCAT(distinct topics.title ORDER BY topics.title ASC SEPARATOR ', ') as titles
    FROM books
    LEFT JOIN book_author ON book_author.book_id = books.id
    LEFT JOIN book_topic ON book_topic.book_id = books.id
    LEFT JOIN authors ON book_author.author_id = authors.id
    LEFT JOIN topics ON book_topic.topic_id = topics.id
    group by books.id


    Этот SQL-запрос решает проблему дублирования книг при нескольких авторах и нескольких рубриках
    Ответ написан
    1 комментарий
  • Запрос Mysql из двух взаимозависимых таблиц

    @bobzer
    Java EE Developer
    Если вам нужны именно пользователи, то основную таблицу запроса удобнее будет взять users:

    select distinct us.* from users us
    inner join comments com on com.user_id = us.user_id
    order by com.date
    Ответ написан
    2 комментария
  • Как сделать чтобы при вставке значения, первое из дублирующихся значений вставлялось, а все последующие обновлялись?

    @bobzer
    Java EE Developer
    1. Можно попробовать триггеры с вашей специфической логикой: создаёте триггер на insert/update в таблицу, а внутри него крутите любую бизнес-логику. Если СУБД развернута на более-менее приличных серверах, то 1-10 млн. операций в сутки пройдет без перенапряжения.

    2. Делать работу в коде - открыли транзакцию, и на вашем ЯП читаете/вставляете/обновляете записи в БД, по окончании завершаете транзакцию. Нагрузка чуть больше, чем в п.п. 1, но при грамотном "общении" с СУБД тоже не так уж и велика.

    3. Разбираетесь, почему у вас дубликаты в БД, читаете мануалы по нормализации данных в СУБД, просите проанализировать структуру спецов. После один раз напрягаетесь чтобы сделать нормальную структуру БД, зато потом работаете с БД "правильно" а не путем применения специфических функций (выходящих за рамки стандарта SQL 2008 (обычно хватает стандарта 92-го года))...

    Вот триггер:
    CREATE TRIGGER wc_terms_unique_slug
    BEFORE INSERT ON wc_terms FOR EACH ROW
    BEGIN
    declare
    countDoubles int;
    
    select count(*) into @countDoubles from wc_terms
        where slug = NEW.slug or slug REGEXP CONCAT('(^', NEW.slug, ')([\-])([0-9]+)$');
    if(@countDoubles > 0) then
        SET NEW.slug = CONCAT_WS('-', NEW.slug, @countDoubles + 1);
    end if;
    
    END;

    После его создания делаете обычные insert-ы (без ON DUPLICATE KEY)
    Ответ написан
    6 комментариев
  • Способы хранения и чтения больших объемов данных в Java-приложении под Android

    @bobzer
    Java EE Developer
    Способы хранения и чтения больших объемов данных
    Это именно то, ради чего и разрабатываются СУБД, и именно их и следует использовать.
    Единственным приемлемым на данный момент способом хранения и работы с данными выбрал для себя XML-файлы
    Непонятно, причем тут вообще XML. Стандарт разрабатывался для унификации форматов при обмене информацией, с уклоном в человекочитаемость, в связи с чем избыточен, ресурсоемок и абсолютно не приспособлен для оптимального хранения данных. Даже если решили велосипед изобретать, то XML, пожалуй, худший из всех возможных вариантов. Тогда уж сливайте все в файл с разделителями и пишите собственные механизмы сохранения и выборки. Работать будет быстрее, чем XML, и ресурсов потребует во много раз меньше. При этом, что XML, что файлы с разделителями, что угодно — если вы не используете СУБД для "хранения и чтения больших объемов данных", то с 90% вероятностью можно предположить, что вы делаете что-то не так (если только вы не Гугл, конечно).
    Да и сервер нагружать такими процедурами нельзя, так как работают с ним порядка 150 устройств с этим приложением. Представьте, сколько ему придется в сутки делать таких пачек инсерт-запросов, если для каждого их по 10-30 тысяч и по 3-5 раз в день
    Большинство современных СУБД, будучи установлены на средний современный сервер, с легкостью проглотят пару миллионов инсертов в сутки. Да что там в сутки, буквально позавчера у меня Oracle за час отработал 15 млн инсертов в таблицу с тремя десятками полей, причем в тестовом окружении.
    на планшете…… по 10-30 тысяч и по 3-5 раз в день
    Если это планшет, значит данные генерирует пользователь, а не какой-нибудь автоматизированный датчик. Тут вопрос, что же там такого может нагенерить пользователь? Может вам следует пересмотреть архитектуру приложения? Или нормализовать сохраняемые данные? Это я так, на всякий случай спрашиваю, а то мало ли… У вас ведь грамотный архитектор на проекте есть, да?
    Ответ написан
    Комментировать