2 место Работа с MySql в многопотоке. Блокировка таблиц. Получение id добавленной записи.

Discussion in 'Десятый конкурс статей' started by Karamzin, Dec 16, 2018.

  1. Karamzin

    Karamzin Client

    Joined:
    May 24, 2016
    Messages:
    155
    Likes Received:
    231
    Ниже много текста. Читать это не обязательно, но настоятельно рекомендую.


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

    В корне не согласен с данной точкой зрения. Рынок лишь изменился. И под него надо подстраиваться (всегда!!!).

    Когда-то в яндекс.директ было очень просто. Сейчас - сложнее. Но этот рынок не умер. Он лишь изменился.

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

    Были времена, когда статейники окупались за несколько месяцев. Сейчас - хорошо, если за год.

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

    На сегодня ситуация изменилась. Автоматизация стала намного доступнее, проще. Естественно это отразилось на рынке. Чем сложнее задача/работа - тем больше денег, чем проще - тем меньше денег. Банально из-за конкуренции.

    Раньше работа таксистом приносила очень хорошие деньги. Теперь все таксисты воют и многие уходят с этой работы. Потому что сейчас машина есть у каждого. Смартфон (а значит клиенты) - тоже. Сегодня любой за один день может стать таксистом. Что и происходит. Как я уже сказал - чем доступнее становится работа, тем больше людей ею занимаются, а значит - меньше доходы.

    Сегодня ни кого не удивишь автоматизацией кучи рутинных действий. Но все это - огромная куча всяких сборок скриптов, софта и прочего. Ты уже не знаешь куда скрыться от всего этого говна. У тебя уже по 10 вариантов программ на решение любой задачи. Но большие деньги уже не в автоматизации - большие деньги в тотальной автоматизации.

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

    Что толку от кучи программ между которыми тебе приходится делать кучу ручной работы, совмещать их, скрещивать, экспортировать, контролировать. В таком режиме ты не можешь по настоящему масштабироваться, по настоящему уйти от рутины.

    В написании шаблонов под заказ можно зарабатывать большие деньги. В дорвеях можно зарабатывать большие деньги. В рассылках можно зарабатывать большие деньги и т.д. Но для этого нужно создать один большой комбайн, который будет все делать сам, у которого все будет в одном месте, который можно легко масштабировать.

    А начинается все с базы данных. Только БД может совместить кучу различных, не связанных друг с другом операций. Только она может по настоящему масштабировать бизнес.

    Для многих на данный момент поднять новый сервак под очередную копию зенки - это целое дело. Потому что их надо постоянно контролировать, менять файлы, задания, закачивать новые, удалять старые.

    А теперь представьте, что все данные хранятся в БД. Все задания на выполнение хранятся в БД. Все большие файлы (картинки, видео и т.д.) хранятся централизованно на одном сервере и подкачиваются от туда по мере надобности или хранятся на облаке.

    Представьте, что чтобы отправить новое задание на 10 серваков вам достаточно нажать несколько кнопок в боте телеграма и оно само уйдет в БД, где они сами распределят между собой задания.

    Многие люди занимаются рассылкой через доноров (различные сайты) в личку сайта или на email. Например Авито. Они пишут шаблон, отрабатывают его и уходят на новый сайт. И так по нескончаемому кругу. Но это какой-то тупиковый путь. На отработанных сайтах постоянно появляются новые пользователи, которым можно продолжать слать сообщения.
    Все что для этого нужно - БД, в которой будут собираться абсолютно все пользователи и статусы слали ли им уже сообщение.

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

    Не нужно иметь миллион сгенерированных вариантов оффера/креатива для каждого сайта, кучу папок в которых постоянно путаешься и тратишь на них уйму времени.

    Не нужно генерировать миллион редиректов в файлах, которые потом раскидывать по всем директориям. Один раз сгенерировав и сохранив в БД - имеете четкое понимание, где какой редирект уже использовался. Их вообще не нужно генерировать заранее, их нужно создавать по мере необходимости.

    Общий принцип для разных видов рассылок (email, личка) должен быть такой:
    Получили задание из БД.
    Взяли из БД спинтакс и сгерерировали из него текст.
    Сгенерировали редирект - вставили его в письмо (и возможно в БД, для работы с другим сайтом).
    Сгенерировали фото/пдф.
    Отправили письмо.

    И так каждый поток, не зависимо от того сколько серверов.
    При этом постоянно парсятся новые "контакты" и добавляются в БД. А скрипт благодаря проектированию БД и статусам сам знает по какому оферу, с каким аккаунтом, с каким контактом он еще не работал и постоянно "подхватывает" в работу новые появившиеся контакты, отправляя им необходимые офферы.

    Таким же образом новые офферы, которые добавляются в БД подхватываются и обрабатываются. В общем тотальная автоматизация и ни какой возни с миллионами списков и таблиц.

    Вы заметили, что все ниши которые я перечислил (даже такси) изменились/усложнились? И главное их изменение - появилась автоматизация, которая стала доступна абсолютно всем.

    Поэтому ваша задача: делать то что не могут другие. Ваша задача создать: создать комбайн.
    Да, создать такой комбайн - чуточку тяжелее, чем то к чему вы привыкли. Но как я уже сказал: чем сложнее - тем больше денег.

    Начинаем учиться:
     
    Last edited: Dec 17, 2018
    ibelieve, one, Alex733 and 12 others like this.
  2. Karamzin

    Karamzin Client

    Joined:
    May 24, 2016
    Messages:
    155
    Likes Received:
    231
    К сожалению я не научу вас делать такие комбайны. Но постараюсь направить вас в нужное русло. Многие из вас уже работают с БД. Надеюсь у меня получится объяснить вам как работать с БД в многопотоке. И если вам что-то будет не понятно, не отчаивайтесь и не пугайтесь - учитесь. Помните: если идете как все, то и зарабатываете как все.
    Многие уже много лет сидят на кубиках, даже не пробуя С#. Пора бы уже поменять свой подход к работе. Поверьте, результаты не заставят себя долго ждать.

    Работа с БД выглядит примерно следующим образом:
    1. Подключение к БД
    2. Открытие сессии
    3. Выполнение произвольного количества запросов
    4. Закрытие сессии
    Особенность работы стандартными методами зенки в том, что она упрощает для пользователя всю эту работу, но в тоже время и сильно его ограничивает.

    Зенка все эти действия выполняет одной строчкой. Это просто. Но если нам надо выполнить множество запросов в рамках одной сессии, то у нас это не получится.

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

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

    Что же делать? Можно использовать костыли: 1 2 3 4 5

    А можно обратиться к стандартной библиотеке для работы с MySql и научиться с ней работать. А чтобы крыша не ехала от обилия строчек в коде - даже упростить всю работу в простые методы одной строкой.

    Чем меньше кода перед глазами, тем проще. Особенно - для новичков.
    Поэтому подключение к БД я вывел в общий код. Данные доступа к БД - в настройки.

    Подключаемся к БД двумя короткими строчками:
    PHP:
    1. Sql sqlConn = new Sql(project);
    2. var cmd = sqlConn.Cmd();
    Далее открываем сессию:
    PHP:
    1. cmd.Connection.Open();
    в рамках которой и будем отправлять все запросы. Каждый поток работает в рамках своей сессии.

    Если таблица заблокирована (об этом позже), то поток ждет, когда её разблокируют и уже в порядке очереди работает с ней.

    Перед каждым запросом мы в свойство cmd.CommandText кладем сам запрос:
    PHP:
    1. cmd.CommandText = "SELECT id FROM phone WHERE phone='79808786445' LIMIT 1;";
    Далее выполняем его:
    PHP:
    1. cmd.ExecuteScalar();
    В данном случае выполняется скалярный запрос, который возвращает одну строку состоящую из одного столбца. Короче говоря возвращает ячейку таблицы.

    Чтобы выполнить запрос без ответа:
    PHP:
    1. cmd.CommandText=String.Format("UPDATE advert SET status='busy' WHERE id={0};", idadvert);
    2. cmd.ExecuteNonQuery();
    Таким запросом можно добавить запись в БД.

    Если мы хотим добавить запись и получить id только что добавленной записи, то мы должны выполнить еще один запрос:
    PHP:
    1. "SELECT last_insert_id();"
    В итоге добавление + получение id будет выглядеть так:
    PHP:
    1. cmd.CommandText = "INSERT INTO advertise SET text='Тестовый текст'";
    2. cmd.ExecuteNonQuery();
    3. cmd.CommandText = @"SELECT last_insert_id();";
    4. cmd.ExecuteScalar();
    Получить данные из таблицы:
    PHP:
    1. cmd.CommandText = String.Format("SELECT * FROM advertise ORDER BY id DESC LIMIT 5;");
    2. var reader = cmd.ExecuteReader();
    Перед тем как начать считывать данные из reader методом .Read() (reader.Read()) необходимо убедиться, что данные вообще имеются в reader, иначе будет исключение (ошибка).

    Проверка делается следующим образом:
    if(reader.HasRows) - свойство HasRows объекта reader возвращает либо true либо false. Если true - значит данные имеются и можно начинать считывание:
    PHP:
    1. while (reader.Read())
    2. {
    3.     string dbId = reader["id"].ToString();
    4.     string dbText = reader["text"].ToString();
    5.     string dbPhone = reader["phone"].ToString();
    6.  
    7.     project.SendInfoToLog(string.Format("id: {0}, text: {1}, phone: {2}", dbId, dbText, dbPhone));
    8. }
    Данные считываются в цикле while. Т.е. перебирается строчка за строчкой пока не закончатся строки.

    reader["id"] - id - название столбца в таблице. Т.к. данные из reader считываются как тип object, то их необходимо привести к нужному нам типу. В данном случае string, но вы можете конвертировать объект в любой тип данных: число, строка, время, дата и т.д. Например:
    PHP:
    1. Convert.ToInt64(reader["phone"])
    Полученные данные сохраняйте в переменные, таблицы, списки и т.д.

    Если выполнили все запросы, то закрывайте сессию:
    PHP:
    1. cmd.Connection.Close();
    Расширения методов
    Когда вам нужно на одно действие писать как минимум 2 строки (а порой и 4), то очень скоро от обилия всего этого многообразия начинает пухнуть голова и начинаешь путаться.

    Поэтому с помощью расширений о которых писали в предыдущем конкурсе я немного упростил работу, сделав всё одной строкой:
    PHP:
    1. object o = cmd.ExScalar(scalarQuery); //Скалярный запрос
    2. int i = cmd.ExNonQ(nonQuery); //Запрос без ответа
    3. long l = cmd.ExQWithLastID(withIdQuery); //Запрос, в ответе которого получаем ID добавленной записи.
    4. var reader = cmd.ExReader(readQuery); //Запрос, в ответе которого получаем строки данных
    Обратите внимание, что скалярный запрос cmd.ExScalar() возвращает тип object, поэтому если хотите получить какой-то конкретный ответ, то результаты конвертируйте в нужный вам тип данных:
    PHP:
    1. Convert.ToDouble();
    2. Convert.ToString();
    3. Convert.ToBoolean();
    4. Convert.ToInt64();
    и т.д...
    Пример:
    PHP:
    1. bool o = Convert.ToBoolean(cmd.ExScalar(scalarQuery));
     

    Attached Files:

    Last edited: Dec 17, 2018
    nycdude, Sanekk, afk and 8 others like this.
  3. Karamzin

    Karamzin Client

    Joined:
    May 24, 2016
    Messages:
    155
    Likes Received:
    231
    Блокировка таблиц

    Теперь можно перейти к блокировке таблиц:
    PHP:
    1. "LOCK TABLES advertise WRITE, phone WRITE";
    Здесь мы блокируем таблицу advertise на запись (WRITE) и таблицу phone на запись (WRITE)
    Также есть блокировка READ. Какие блокировки использовать читайте например здесь или в других подобных статьях.

    Я также сделал расширение одной строкой
    PHP:
    1. cmd.DbLock("advertise WRITE, phone WRITE");
    Напомню, что стандартное исполнение выглядело бы так:
    PHP:
    1. cmd.CommandText = "LOCK TABLES advertise WRITE, phone WRITE";
    2. cmd.ExecuteNonQuery();
    В качестве параметров соответственно перечисляем какие и как блокировать таблицы: "advertise WRITE, phone WRITE"

    Т.е. если у вас 10 таблиц, а вам нужно заблокировать одну таблицу, но работать в рамках сессии вы будете с тремя таблицами, то вот эти три таблицы вы и должны заблокировать.

    Разблокировка таблиц
    происходит следующим образом:
    PHP:
    1. "UNLOCK TABLES;"
    Также подготовил соответствующее расширение:
    PHP:
    1. cmd.DbUnLock();
    Предобработка текста
    Также стоит поговорить об обработке текста, который вы шлете в БД. Если вы попытаетесь добавить в БД текст со спец символами без предварительной обработки, то получите ошибку. Например: Men's health.
    Верхний апостроф испортит всю малину. Таких символов достаточно много.
    Решается задача следующим образом:
    PHP:
    1. string text = "Men's health";
    2. cmd.Parameters.AddWithValue("@text", text);
    Количество параметров добавляете по необходимости:
    PHP:
    1. cmd.Parameters.AddWithValue("@text", text);
    2. cmd.Parameters.AddWithValue("@title", title);
    3. cmd.Parameters.AddWithValue("@tags", tags);
    4. cmd.ExNonQ(string.Format("INSERT INTO advertise SET text={0}, title={1}, tags={2}", "@text", "@title", "@tags));
    Обратите внимание на SET text={0}
    Когда применяете параметры, ни в коем случае не ставить апострофы text='{0}' - не будет работать.
     
    Last edited: Dec 16, 2018
    Sanekk, afk, Sobesednic and 3 others like this.
  4. Karamzin

    Karamzin Client

    Joined:
    May 24, 2016
    Messages:
    155
    Likes Received:
    231
    Примеры с irr

    Давайте немного углубимся на примере доски объявлений.

    В шаблоне я постарался максимально закомментировать все что только можно. Но пройдемся по нему и здесь.

    На бегете арендован тестовый сервер на месяц. Можно на нем поиграться немного. Все пароли присутствуют в шаблоне.

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

    Принцип следующий:
    1. В БД попадает задание в таблицу tasks (например через телеграм).
    2. Шаблон с заданной периодичностью подключается к БД.
    3. Получив доступ к телу БД, он первым делом блокирует таблицу и ищет задание:
    PHP:
    1. SELECT id, link FROM tasks WHERE STATUS='execute' LIMIT 1;
    Т.е. его интересует строка со столбцом STATUS='execute' (т.е. к выполнению).

    Если он такую не находит, то шаблон завершает свою работу, иначе:
    4. Получает id (номер задания) и link (само задание).
    5. Далее меняет статус строки (задания) с execute на busy (т.е. в работе).
    6. Разблокирует таблицу.


    Далее во втором снипете Парсинг категорий irr.ru - пример работы.

    1. Get-запросом парсится страница Irr (с помощью библиотеки HtmlAgilityPack).
    2. В ней находим объявления.
    3. У каждого объявления парсим только id и его ссылку (для простоты примера, иначе будет много кода)
    4. Проверяем нет ли уже этого объявления в БД.
    Если есть, то переходим к следующему объявлению на данной странице.
    5. Если нет, то добавляем в БД.
    6. Повторяем по циклу.
    7. Разблокируем таблицу.

    Третий снипет рабочий, но не доделанный.
    Не реализован get-запрос к сайту и получение реального телефона.
    Также нет цикла :-))
     
    Last edited: Dec 17, 2018
    Kirillzenp, Sanekk, Osedjuse and 7 others like this.
  5. lzlmrf

    lzlmrf Client

    Joined:
    Aug 14, 2015
    Messages:
    455
    Likes Received:
    123
    очень актуально сейчас. После перехода на базы данных не представляю как работал раньше с кучей файлов в разных папках. :-)
    По поводу блокировки таблиц хотел узнать у вас..
    Есть таблица с акаунтами при работе с которой в небольшое количество потоков (30-40) проблем нет. Но когда шаблон стал работать на запросах в 300-400 потоков я вижу что таблица лочится просто и потоки висят в ожедании получения . И по времени получается что прирост мизерный.
    /////db conect

    string connect_db= project.Variables["conect_to_DB"].Value;

    // данные для вставки
    string[] _account = project.Variables["string_accs_for_base"].Value.Split(new Char[]{':'});

    //в strDB получили status IS NULL OR status = 0
    string strQuery =("select * from profiles where status='0' and valid='Y' and unique_name<>'' ORDER BY take_time ASC LIMIT 1");

    lock (SyncObjects.InputSyncer) {
    strDB = ZennoPoster.Db.ExecuteQuery(strQuery, null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, connect_db, " ¥ ");

    string[] splitit = strDB.Split(new Char[]{'¥'});
    string id_BD=project.Variables["id_BD"].Value =splitit[0].Trim();
    project.Variables["name"].Value =splitit[1].Trim() ;
    project.Variables["fb_login"].Value =splitit[2].Trim() ;
    // все остальные переменые
    strQuery =string.Format(@"UPDATE `profiles` SET `status`='1' where `id` ='{0}' ",id_BD);//изменяю статус на 1 чтоб другой поток не получил этот акаунт
    count_update = ZennoPoster.Db.ExecuteNonQuery(strQuery, null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, connect_db);//}
    project.SendInfoToLog(string.Format(@"{0}",t_univer,true));
    }
    return count_update; // проверяю количество изменений после запроса, тоесть если 1 то неполучилось сделать апдейт и акаунт взят другим потоком
    ---------------------------
    Как бы вы реализовали подобное , чтобы небыло проблем с получением 1 ака несколькими потоками и чтобы небыло долгого ожедания при большом количестве потоков ?
     
  6. WebBot

    WebBot Client

    Joined:
    Apr 4, 2015
    Messages:
    969
    Likes Received:
    500
    Дак вот из-за кого мне саппорт тему про MySQL не утвердил, сказав что про это уже пишут ;-)))
     
    one and Lord_Alfred like this.
  7. Lord_Alfred

    Lord_Alfred Client

    Joined:
    Oct 9, 2015
    Messages:
    3,000
    Likes Received:
    2,550
    Как и написано выше - отказаться от "ZennoPoster.Db" и юзать либу MySQL.

    PS: @DmitryAk, надеюсь тебе придёт уведомление ) Может быть пора народу увидеть дбхелпер? Или хотя бы тем, кто сможет помочь в его доработке - выдать доступы? Думаю, @Karamzin приятно удивился бы уменьшению количества строк кода)
     
    AZANIR, Nike59 and lzlmrf like this.
  8. WebBot

    WebBot Client

    Joined:
    Apr 4, 2015
    Messages:
    969
    Likes Received:
    500
    Я бы присмотрелся к GET_LOCK / RELEASE_LOCK
     
    lzlmrf likes this.
  9. BblTPE3BUTEJlb

    BblTPE3BUTEJlb Client

    Joined:
    Sep 4, 2014
    Messages:
    108
    Likes Received:
    152
    Зачем вы вообще юзаете mySQL при таких вводных? Мазохизм нравится? :ap:
    Вот реально многим проще костыли к мускулю прикрутить, чем взять инструмент, где проблема многопотока не проблема вовсе и решена из коробки.
     
    goldfish likes this.
  10. molotok

    molotok Client

    Joined:
    Apr 17, 2015
    Messages:
    378
    Likes Received:
    119
    Это что за инструмент?
     
  11. Karamzin

    Karamzin Client

    Joined:
    May 24, 2016
    Messages:
    155
    Likes Received:
    231
    1. Для начала надо внимательно изучить то что я написал.
    2. Потом изучить шаблон
    3. Внимательно изучить снипет: Получение заданий в многопотоке из БД. Это то что тебе нужно.
    4. Отказаться от костылей о которых я говорил lock (SyncObjects.InputSyncer), и применить уже наконец адекватные инструменты, которые я описал и привел конкретные примеры в шаблоне.
    5. Изучить оптимизацию БД
    6. Проиндексировать таблицы.
    7. Грамотно спроектировать БД. Советую очень лаконичный, краткий, понятный курс
    8. Во время блокировки таблицы выкинуть все лишние действия. Ибо блокировка таблицы хотя бы на 1 секунду в 300-400 потоков привет к очереди в 5-7 минут. В общем изучи снипет из шаблона. Там есть ответ на твой вопрос.

    Удивить меня не получится, ибо один платный у меня есть. Но хорошим инструментам всегда рад. Так что где там ваш хелпер? :-)
    За столько лет ни кто так и не дал ни инструкции как работать в многопотоке с БД ни хелперов. Ни думаю, что в ближайшие годы он появится :ah:

    Прошу прощения был не прав. Информацию дали в этом курсе еще пару лет назад (который я настоятельно рекомендую), но люди почему-то вместо того чтобы заплатить - занимаются мазохизмом.
     
    Last edited by a moderator: Dec 18, 2018
    afk likes this.
  12. goldfish

    goldfish Client

    Joined:
    Jun 6, 2011
    Messages:
    180
    Likes Received:
    12
    а какие это инструменты?
     
  13. Lord_Alfred

    Lord_Alfred Client

    Joined:
    Oct 9, 2015
    Messages:
    3,000
    Likes Received:
    2,550
  14. ssXXXss

    ssXXXss Client

    Joined:
    Dec 23, 2014
    Messages:
    6,954
    Likes Received:
    1,780
    покажи мне пример из коробки
    у меня файл 10 лямов
    да твоя коробка раком загнётся
     
  15. Lord_Alfred

    Lord_Alfred Client

    Joined:
    Oct 9, 2015
    Messages:
    3,000
    Likes Received:
    2,550
    Hadoop?

     
  16. ssXXXss

    ssXXXss Client

    Joined:
    Dec 23, 2014
    Messages:
    6,954
    Likes Received:
    1,780
    у меня 1200 потоков
    ну и я просил из коробки
    я так понял из коробки зенки
     
  17. ssXXXss

    ssXXXss Client

    Joined:
    Dec 23, 2014
    Messages:
    6,954
    Likes Received:
    1,780
    Вытрезвитель выложил тему бнеспонтовую, вычитает, выложит, и такая чушь реально, мы ведь знакомы вытрезвитель ??? ))))))))))))))))))))))
     
  18. Lord_Alfred

    Lord_Alfred Client

    Joined:
    Oct 9, 2015
    Messages:
    3,000
    Likes Received:
    2,550
    Из коробки зенки, к сожалению, вообще ничего не придумать :(
     
  19. ssXXXss

    ssXXXss Client

    Joined:
    Dec 23, 2014
    Messages:
    6,954
    Likes Received:
    1,780
    ну тут форум зенки
    тогда смысл писать про коробку ?

    а вообще можно, если каждый внесёт в неё что то, не на форуме а админам, а там как вы договоритесь, если тема реальная то не думаю что они не заплатят и мимо пройдут
    а тут просят выложите бесплатно )))))))))))))
    и что бы потом ещё обсирать что сука ошибку выдаёт из за его кривых рук
     
    Last edited by a moderator: Dec 19, 2018
    Lord_Alfred likes this.
  20. BblTPE3BUTEJlb

    BblTPE3BUTEJlb Client

    Joined:
    Sep 4, 2014
    Messages:
    108
    Likes Received:
    152
    Lord_Alfred направление мысли верное, но слишком глобальное. Все гораздо проще.
    От таблиц надо только заставить себя отказаться, а это у многих происходит через ломку :D
     
  21. ssXXXss

    ssXXXss Client

    Joined:
    Dec 23, 2014
    Messages:
    6,954
    Likes Received:
    1,780
    так минимизируй глобальность умом ))))))))
     
  22. Moadip

    Moadip Client

    Joined:
    Sep 26, 2015
    Messages:
    432
    Likes Received:
    580
    Сначала работаешь с голыми sql запросами, потом начинаешь юзать какие то обертки поверх, методы зенки, свои самописные, или чужие.
    Потом с sql надоедает возиться вообще, и начинаешь писать методы поверх sql, которые "перегоняют" инфу из таблиц в классы/объекты, если конечно они есть, т.к. с ними удобнее работать, и обратно в бд, ну типа "маппинг" костыльный.
    И потом ты плавно переходишь на ORM.:-)
    NHibernate, Entity Framwork и т.д. и т.п.
    Вот там реально сокращается кол-во кода.

    Когда БД выглядит примерно вот так, на одном голом sql далеко не уедешь.

    upload_2018-12-20_22-57-47.png

    Самый очевидный вариант, это начать с Entity Framwork. Но не самый удобный.
    Получается как правило сначала есть бд. Потом на основе ее модели надо сгенерить классы. Потом если что то изменить в базе, надо "перегенерить" классы.
    Вот тут то у неподготовленного юзера могут возникнуть куча трабл.

    Покопавшись в гугле, нашел для себя вариант, решения от devart(не реклама :D). Там сразу идет куча коннекторов к разным БД, плюс есть отдельная прога EntityDeveloper с помощью которой можно легко в пару кликов обновить "старую" модель на "актуальную" и перегенерить классы. Кому инересно, можно буквально за вечер потестить что это и как юзать, все работает из коробки.
    Есть один минус. Эти решения платные. Но кто ищет, то всегда найдет как решить эту проблему.:-)

    И еще момент, ORM я бы назвал узкоспециализированным решением, не всем оно нужно.
    Если в БД пару таблиц и несколько типизированных запросов, то смысла нет.
    Но когда идет плотная работа с БД, и переодически добавляются новые таблицы и связи, то имхо, без ORM не обойтись.
    Плюс на первое место выходит удобство работы.
    Со строчками таблицы работаешь как с объектами, с доступом к нужным "ячейкам" через свойства объекта, LINQ и т.д.
     
    Zymlex, Sanekk, dio-dev and 4 others like this.
  23. Karamzin

    Karamzin Client

    Joined:
    May 24, 2016
    Messages:
    155
    Likes Received:
    231
    Круто. То что нужно. Вот этим удивил.
     
  24. Lord_Alfred

    Lord_Alfred Client

    Joined:
    Oct 9, 2015
    Messages:
    3,000
    Likes Received:
    2,550
    Всё верно, только когда БД разрастается в неприличные объемы, то потом появляются проблемы со скоростью, а это значит, что приходится отказываться от ORM и переписывать все запросы в "голый" формат.
    Это я так, к сведению, был печальный опыт давным давно ))

    А в целом, любопытно и интересно. Devart явно стоит посмотреть, но вообще дбхелпер, про который я тут вскользь упоминал - как раз умеет генерить классы из таблиц и потом работать через них. И он не идеальный, да, но скорее всего для нужд зенки - самое то :-)
     
    Zymlex, Moadip and Karamzin like this.
  25. Moadip

    Moadip Client

    Joined:
    Sep 26, 2015
    Messages:
    432
    Likes Received:
    580
    Думал над этим, скорость не критична. По крайней мере пока. Дальше видно будет.

    А вот это уже интересно. Ждем релиза.:-)
     
  26. Karamzin

    Karamzin Client

    Joined:
    May 24, 2016
    Messages:
    155
    Likes Received:
    231
    А в чем отличие работы? Почему скорость падает?
     
  27. Sz5

    Sz5 Client

    Joined:
    Dec 10, 2012
    Messages:
    153
    Likes Received:
    151
    Любая обертка будет добавлять свой дополнительный слой взаимодействия => ресурсы также будет затрачиваться дополнительные.
     
  28. Lord_Alfred

    Lord_Alfred Client

    Joined:
    Oct 9, 2015
    Messages:
    3,000
    Likes Received:
    2,550
    Тут скорее на больших базах (как по объему, так и количеству таблиц и сложности запросов) этот вопрос "встаёт ребром", т.к. универсального инструмента не существует, везде какие-то ограничения или хаки для таких баз приходится юзать, особенно если писать очень большие запросы (где куча связей, выборки в выборках, временные таблицы и тд). Поэтому часто в такой ситуации проще отказаться от ORM и использовать "голый sql", т.к. на нём то наверняка можно описать всё что нужно, правда, выглядеть это возможно будет не так красиво как хотелось (вспоминаем про запросы в 10+ строк), потому что когда база обрастает со временем связями - архитектура страдает и иногда лучше всё переделать в процессе, чем получить в итоге вот это всё :-)
     
  29. Moadip

    Moadip Client

    Joined:
    Sep 26, 2015
    Messages:
    432
    Likes Received:
    580
    Не только из за этого.
    Когда делается запрос на чистом sql, то тащится только то, что надо. К примеру есть таблица, и связанные с ней еще скажем 2.
    Если инфа из 2 связанных не нужна, можно взять инфу только из основной.

    Если через ORM, то там по запросу будет тащить все, чтобы была возможность через свойства получить доступ к инфе доп. таблиц.
    Конечно там тоже есть ухищрения некоторые, частичная подгрузка, ну или типа ленивая, можно написать запрос на sql и т.д.

    Но все равно да, будут тормоза, даже при всех ухищрениях, тк в первую очередь любая "прокладка" отнимает ресурсы, а дальше на каком этап это вылезет(на каком объеме данных).))
     
    Sz5 and Lord_Alfred like this.
  30. one

    one Client

    Joined:
    Sep 22, 2015
    Messages:
    5,213
    Likes Received:
    873
    А где почитать с примерами как работать с этой самоу либой и как она вообще называется то? Секретная не? )
     

Пользователи просматривающие тему (Пользователей: 0, Гостей: 0)