На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! информация о разделе
user posted imageДанный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ.

Модераторы: Pr0[)!9Y, Akina, JoeUser
  
> SELECT к двум хостам (MYSQL)
    Добрый день.

    Я немного упрощу описание проблемы и заменю названия для наглядности.

    У меня два сервера, на первом хранятся МУЖИКИ с id-шниками. На втором БАБЫ тоже с id-шниками.

    На первом сервере, в таблицу с МУЖИКАМИ первого сервера добавил ручками столбец "WomanId" и забил туда по нужным мне соответствиям(ну скажем это жены ихние) id-шники БАБ со второго сервера.

    Получилось что-то типа такого:
    ManId____ManName_______WomanId
    1025_____Игорь_________541
    1021_____Борис_________645

    Мне нужно получить на первом сервере данные в таком виде:
    Имя мужика/Имя бабы

    Как я делал:
    ExpandedWrap disabled
      $result1 = mysqli_query($server1, 'SELECT ManId, ManName, WomanId FROM bd1.Man;');
      while ($row1 = mysqli_fetch_array($result1)) {
          $result2 = mysqli_query($server2, 'SELECT WomanName FROM bd2.Woman WHERE WomanId ='.$row1[2].';');
          while ($row2 = mysqli_fetch_array($result2)) {
              echo $row1[1]." ".$row2[0]."</br>";  
          }
      }


    Получаю нужные мне "Имя мужика/Имя бабы"
    Но, мужиков у меня больше 1000, в итоге в цикле отправляется 1000+ запросов к второму серверу с бабами, это работает, но очень медленно.

    На mssql получал список баб одним запросом:
    Формировал xml: <row id = "1025">541</row> <row id = "1021">645</row>
    и отправлял запрос к второму серверу "declare @xml xml SET @xml='<row id = "1025">541</row> <row id = "1021">645</row>...

    Т.е. я прописывал в xml соответствия мужик_id/баба_id и второй сервер мне возвращал данные в таком виде
    ManId(который я же ему и отправлял в xml)/и имя бабы
    1025/Света
    1021/Люся

    После чего, слинковать баб к мужикам по id из запроса плевое дело.
    Можно как нибудь так же, одним запросом на mysql сделать?(Модифицировать базы нельзя only read, настраивать базы, прописывать линки нельзя, only php и only read)
    Ну или может еще какие варианты есть?

    Спасибо.
      На первый сервер шлёшь запрос

      ExpandedWrap disabled
        SELECT ManId, ManName, WomanId
        FROM bd1.Man;


      Полученные данные валишь в массив.

      Все полученные WomanId собираешь в одну переменную, разделяя значения запятыми, и шлёшь на второй сервер запрос

      ExpandedWrap disabled
        SELECT WomanId, WomanName
        FROM bd2.Woman
        WHERE WomanId IN (WomanId-1, WomanId-2, ... , WomanId-N);


      Полученные данные валишь во второй массив.

      Затем объединяешь массивы в один по равенству поля WomanId.

      Всё.

      PS. Возможная ошибка - попытка вставить переменную со списком как параметр. В этом случае список будет обрамлён кавычками и воспринят как один длинный литерал, а не список.
      Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
      Есть претензии ко мне как к участнику? да ради бога.
      Не нравятся мои ответы? не читайте их.
      В общем, берегите себя. Нервные клетки не восстанавливаются.
        Цитата Akina @
        Затем объединяешь массивы в один по равенству поля WomanId.

        А как объеденить то?))
        Тут сортировка нужна сравнивать ID то что пришло от баб и те бабские ID которые у мужиков были.
        Потому что приходит ответ не сортированный ну никак, да и даже если бы был сортированный, у меня мужиков к примеру тысяча, а ID баб подбиты 900 к примеру - так что в цикле тоже не рассортируешь - нужен алгоритм посложнее.
        А сортировка, поверь, по скорости практически тоже самое, что юзать так, как я написал. Ну мб чуть быстрее. Делал я так. Не варик.

        Варик - это получить WomanID вместе с отправляемыми ManID - тогда можно сразу найти нужный тип/массив по ManID и записать туда WomanName.

        Т.е. я отправляю на бабский сервер xml с мужскими и женскими ID, джойню с таблицей Woman и получаю ответ из бд и из xml. Из xml ManID, из бд WomanName.
        Тогда мне ответ приходит такой: ManID|WomanName, мне не надо сортировать, я просто ложу WomanName по ManID.
        Вот что я бы хотел, но у меня проблема с синтаксисом - не могу переписать запрос с mssql на mysql.

        Вот то, что я пытался сваять из рабочего mssql запроса и нужного мне mysql. Но ошибка, как исправить не знаю...
        $qer формирую когда получаю ответ от первого сервера.
        Примерно так:
        ExpandedWrap disabled
          $qer.=('<row id = "'.$id_one[$row[0]].'">'.$id_two[$row[0]].'</row>');



        ExpandedWrap disabled
          DECLARE xml TEXT;
          SET xml='<rows>".$qer."</rows>';
          SELECT Art.SortKey, t1.PRICE, t2.VALUE FROM
          (select b.value('@id' , 'int') [SortKey], b.value('.' , 'varchar(50)') [ArtNo] FROM @xml.nodes('/rows/row') a(b) )as Art LEFT JOIN
          b_catalog_price AS t1 ON t1.PRODUCT_ID = Art.ArtNo LEFT JOIN
          b_iblock_element_property AS t2 ON t2.IBLOCK_ELEMENT_ID = t1.PRODUCT_ID AND t2.IBLOCK_PROPERTY_ID = 47
        Сообщение отредактировано: Rzonex -
          Цитата Rzonex @
          А как объеденить то?

          Понятия не имею - я в ПХП ни ухом ни рылом... но вроде как там функций для обработки массивов море, неужто не найдётся объединение по ключу?
          Цитата Rzonex @
          А сортировка, поверь, по скорости практически тоже самое, что юзать так, как я написал.

          Фигню говоришь. Добавь в запрос нужный ORDER BY, и получишь результат уже сортированным. И поверь, это будет гораздо быстрее, чем сортирить на клиенте (кстати, уж сортирить массивы ПХП сто пудов умеет).
          Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
          Есть претензии ко мне как к участнику? да ради бога.
          Не нравятся мои ответы? не читайте их.
          В общем, берегите себя. Нервные клетки не восстанавливаются.
            Цитата Akina @
            Фигню говоришь.

            Я имел в виду сортировку в самом php.
            У меня объявлен тип, в котором я храню всю нужную информацию. Идентификатором этого типа является ManID.
            Вот пришел мне запрос с голыми WomanName, ну и WomanID. А мне каждую бабу эту нужно записать в php тип. Но куда?
            А туда где WomanID из запроса будет равен WomanID типа.
            Как это сделать? Самое простое - создать еще тип, добавить в него все поля из запроса, и крутить сравнение в цикле - если совпало,
            записывать один тип в другой и удалять тот который из запроса был создан. В итоге получаем простейшую сортировку.
            А без этого, рассортировать запрос в тип я не могу.
            И такие костыли я уже делал. Оно плохо работает, оно мне не по душе, оно мне не нравится.
            А мне нравится послать xml к бабам и получить в лтвете баб и id мужиков, чтобы я сразу мог результат в php записать в нужный мне тип.
            Сообщение отредактировано: Rzonex -
              Цитата
              Мне нужно получить на первом сервере данные в таком виде:
              Имя мужика/Имя бабы

              вот тебе костыль вариант 1
              ExpandedWrap disabled
                    
                    $result1 = mysqli_query($server1, 'SELECT ManId, ManName, WomanId FROM bd1.Man;');
                    $result2 = mysqli_query($server2, 'SELECT WomanId, WomanName FROM bd2.Woman;');
                    for ($res1 = array(); $tmp = $result1->fetch_array(MYSQLI_ASSOC);) $res1[] = $tmp;
                    for ($res2 = array(); $tmp = $result2->fetch_array(MYSQLI_ASSOC);) $res2[] = $tmp;
                    foreach($res1 as $man){
                      foreach($res2 as $woman){
                        if ($man['WomanId'] == $woman['WomanId']) {
                          echo $man['ManName']." ".$woman['WomanName']."</br>";
                          break;
                        }
                      }
                    }

              вот тебе костыль вариант 2
              ExpandedWrap disabled
                    $result1 = mysqli_query($server1, 'SELECT ManId, ManName, WomanId FROM bd1.Man;');
                    $result2 = mysqli_query($server2, 'SELECT WomanId, WomanName FROM bd2.Woman;');
                    $womans = array();
                    while ($row2 = mysqli_fetch_array($result2)) { $womans[$row2['WomanId']] = $row2['WomanName']; }
                    while ($row1 = mysqli_fetch_array($result1)) {
                      echo $row1['ManName']." ".$womans[$row1['WomanId']]."</br>";  
                        }
              Сообщение отредактировано: Gonarh -
                Цитата Rzonex @
                Я имел в виду сортировку в самом php.

                ЗАЧЕМ? Оставь решение задачи сортировки тому, кто умеет это делать лучше - серверу MySQL.
                Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
                Есть претензии ко мне как к участнику? да ради бога.
                Не нравятся мои ответы? не читайте их.
                В общем, берегите себя. Нервные клетки не восстанавливаются.
                  Цитата Akina @

                  Так я этого и добиваюсь))) Но что бы мне не делать сортировку в php - мне нужны данные от мускула в виде ManId/WomanName

                  Цитата Gonarh @
                  вот тебе костыль вариант 1

                  У меня на обоих сайтах овер 1000 записей. Тут у тебя два вложенных цикла, это миллион итераций. Это будет работать, но это костыль.
                  Добавлю, что у меня не два сайта а 4. Это при 1000 записей 4 милиона итераций, при 2000 будет уже 16 лямов, рост в геом. прогрессии.
                  Если оптимизировать, то нужно делать правильно. А ваш вариант это костыль, уж простите.

                  Ну разве нельзя отправить на второй сервер запрос с xml с ManID|WomanId?
                  Чтобы он вернул ManId|WomanName???
                  Сообщение отредактировано: Rzonex -
                    Второй вариант - двухпроходный цикл

                    Добавлено
                    Цитата Rzonex @
                    Это при 1000 записей 4 милиона итераций, при 2000 будет уже 16 лямов, рост в геом. прогрессии.

                    Не будет там 16 млн итераций.

                    Добавлено
                    Цитата Rzonex @
                    Ну разве нельзя отправить на второй сервер запрос с xml с ManID|WomanId?

                    Отправить то ты можешь, только там ManID нахер не нужон.
                      Цитата Rzonex @
                      Ну разве нельзя отправить на второй сервер запрос

                      Можно.
                      Цитата Rzonex @
                      с xml с ManID|WomanId?

                      Можно, но бессмысленно. MySQL не понимает запросов в XML-формате.

                      Озвучьте версию второго MySQL. Можно крупно - 5 или 8?
                      Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
                      Есть претензии ко мне как к участнику? да ради бога.
                      Не нравятся мои ответы? не читайте их.
                      В общем, берегите себя. Нервные клетки не восстанавливаются.
                        Цитата Gonarh @
                        Отправить то ты можешь, только там ManID нахер не нужон.

                        Нет, он там нужон. А для чего? Чтобы он вернулся вместе с WomanName, чтобы мне не сортировать в php потом, не делать вложенных циклов.
                        Я так делал на mssql это работало очень быстро.

                        Цитата Gonarh @
                        Не будет там 16 млн итераций.

                        Да будет меньше, 16 млн, это если искомая запись всегда будет последней в цикле.
                        Я не хочу так делать, у меня скоро пять сайтов будет, а может еще больше. Нужен оптимизированный вариант...
                          Цитата Rzonex @
                          Модифицировать базы нельзя only read, настраивать базы, прописывать линки нельзя, only php и only read

                          Заведите свой, третий, MySQL-сервер, и с него аттачьтесь к первым двум. Обойдётесь одним простым запросом.

                          The FEDERATED Storage Engine
                          Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
                          Есть претензии ко мне как к участнику? да ради бога.
                          Не нравятся мои ответы? не читайте их.
                          В общем, берегите себя. Нервные клетки не восстанавливаются.
                            Цитата Akina @
                            Озвучьте версию второго MySQL. Можно крупно - 5 или 8?

                            У меня скоро пять сайтов будет. Везде разные версии...
                            Цитата Akina @
                            Заведите свой, третий, MySQL-сервер, и с него аттачьтесь к первым двум. Обойдётесь одним простым запросом.

                            Не могу. На сервере, где запускаю скрипт отключен удаленный доступ к бд, точнее он есть но через ssh туннель.
                            Цитата Akina @
                            Можно, но бессмысленно. MySQL не понимает запросов в XML-формате.

                            Очень печально. Может все-таки можно как-нибудь отправить запрос с ManID и соответствующими им WomanID? Чтобы в ответе сохранялся порядок ManID/WomanName?
                            Это все что нужно, это будет работать очень быстро, я так делал...
                            Сообщение отредактировано: Rzonex -
                              Возможное решение-костыль.

                              Делаем первый запрос на первый сервер.
                              ExpandedWrap disabled
                                SELECT ManId, ManName, WomanId FROM bd1.Man;

                              Получаем, к примеру
                              ManIdManNameWomanId
                              11Петя111
                              12Коля112
                              13Вася113

                              На основании этих данных формируем запрос на второй сервер, который выглядит так:
                              ExpandedWrap disabled
                                SELECT t1.ManName, bd2.WomanName
                                FROM     ( SELECT 'Петя' ManName, 111 WomanId
                                           UNION ALL
                                           SELECT 'Коля', 112
                                           UNION ALL
                                           SELECT 'Вася', 113
                                          ) AS t1
                                LEFT JOIN bd2.Woman ON t1.WomanId = bd2.WomanId;

                              и получаем в ответ
                              ManNameWomanName
                              ПетяКлава
                              КоляОля
                              ВасяNULL

                              Последний NULL означает, что Вася ещё пока неженатый.
                              Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
                              Есть претензии ко мне как к участнику? да ради бога.
                              Не нравятся мои ответы? не читайте их.
                              В общем, берегите себя. Нервные клетки не восстанавливаются.
                                Цитата Akina @
                                Возможное решение-костыль.

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

                                Это песня, это сказка :D Работает очень быстро и никакой это не костыль, а имхо оптимальное решение.

                                Спасибо большое Akina!
                                Сообщение отредактировано: Rzonex -
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script Execution time: 0,1524 ]   [ 15 queries used ]   [ Generated: 24.08.19, 16:09 GMT ]