1. SQL / Говнокод #24336

    0

    1. 1
    2. 2
    //Список категорий записан в строках с разделителем вида "23", "11||12" или даже "3||8||12||43||23"
    SELECT id, pagetitle FROM modx_site_content WHERE categores LIKE "%|[[*id]]" OR categores LIKE "%|[[*id]]|%" OR categores LIKE "[[*id]]|%" OR categores="[[*id]]"

    Запостил: FODD, 29 Мая 2018

    Комментарии (49) RSS

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

          За выбор по лайку в OLTP надо выгонять из профессии навсегда, особенно когда в categores лежит какая-то ненормализованная хуита
          Ответить
          • Я в профессии неделю, а меня уже выгоняют. Бяда.
            Ответить
            • Вогнал тебе. Проверь.
              Ответить
            • Запрос тормозной. Соответствие id->категория нужно хранить в отдельной табличке. Что-то типа такого:
              id = 1, category = 2
              id = 1, category = 5
              id = 2, category = 2
              id = 2, category = 3

              Уникальный ключ будет комплексный: (id, category)

              Тогда можно проиндексировать столбец category и доставать все id, соответствующие категории, мгновенно.
              Ответить
            • То-есть ты неделю назад начал изучать базы данных?
              Тогда купи себе скорее хорошую книжку!
              Ответить
              • Зачем покупать книжку, когда в Интернете полно годной информации нахаляву? И я не имею в виду Мишку Русакова.
                Ответить
                • Ну берешь и кочаешь книжку.
                  Ответить
                  • ПОСОНЫ НЕ КОЧАЙТИ ТАМ ВИРУС КОМП РАСПИДОРАСИЛО ПЕШУ С УТЮГА
                    Ответить
                    • ПОСОЛИЛ МНЕ КОЧЕЛЬКИ САМ ЛИНУС КОМПАС ПИДОРАСЫ ЧЕШУТ ССУТ ЮГА
                      Ответить
                • Потому что хорошие учебники продаются. Конечно, можно бесплатно скачать электронную книгу, но разве можно воровать??
                  Ответить
                  • На "Habrahabr.ru" полно дебилов, готовых тратить своё время на то, чтобы бесплатно учить желающих. Этим и можно воспользоваться.
                    Ответить
                    • Я бы не стал учиться у дибилов.
                      Ответить
                    • вместо разрозненных статеек, написанных нигде не обучавшимися пыхопыхерами, не лучще-ли читать нормальную книгу?

                      А что начитаются всякой mysql.ru, а потом не знают какие бывают виды объединений, не знают что такое CTE и не умеют пользоваться констреинтами.
                      Ответить
                      • Все твои шаблоны легко порушит "Facebook" (второй по величине сайт Интернета): по официальной информации, у них никаких объединений нет, вся информация хранится в одной, распределённой по серверам, таблице, а зависимости между записями в "MySQL" ("лайки", подписчики и т.д.) хранятся в графовой базе данных - единственной наработке, которую они реализвали своими силами, для хранения данных. И таки-имеют весь мир.
                        Ответить
                        • >> у них никаких объединений нет
                          разумеется в системах такого размера не может быть реляционных субд

                          >>хранятся в графовой базе данных
                          ЧИТД

                          Но во-первых проблемы facebook надо решать когда ты размером с facebook, а во-вторых google тоже имеет весь мир, и совсем не хранит все данные в одной колонке mysql:)
                          Ответить
                          • Неужели Гугл хранит данные... в двух колонках?
                            Ответить
                            • Для хранения "всего" минимум нужно 3 колонки: ID|Key|Value, если не делать составной ключ
                              Ответить
                            • конечно в разных колонках. А для поиска использует лайк.

                              Там наверняка есть serp.php, и там написано

                              $resultat = mysql_query("SELECT * from stranici where tekst like '%$zapros%'")

                              Роман, подтверди
                              Ответить
                    • Но для этого нужно самому быть дебилом
                      Ответить
                    • > бесплатно учить желающих...
                      ... своему однобокому пониманию какой-нибудь хуйни.
                      Ответить
            • Разработчики одного микроблога пытались хранить все столбцы в сериализованном виде в одной ячейке (типа как здесь категории сжаты в одно значение, только они так же сжали все поля):
              https://backchannel.org/blog/friendfeed-schemaless-mysql

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

              Кстати, изучи все типы JOIN, оператор GROUP BY и так называемые агрегатные функции.
              Ответить
              • mysql, friendfeed и реляционная база в которой все хранится в одной ячейке -- не нужны
                Ответить
          • А можно объяснить на пальцах, чем различаются все эти OLTP, OLAP, а то похапешнику тяжело читать многобуков?
            Ответить
            • OnLineTransactionProcessing -- сильно нормализованная база данных, удобная для быстрой вставки данных и (в силу своей нормализованности) недопускающая неконсистентности.
              Неудобна для отчетов (надо делать кучу джойнов, медленно).

              OnLineAanalysisProcessing: возможно денормализованная база, возможно генерируется раз в N часов по OLTP. Удобна для быстрого получения отчетов. Может быть как обычная реляционная СУБД так и OLAP куб.

              OLTP
              |ID|UserId|ItemId|Quantity|Timestamp|


              OLAP (реляционный, не куб)
              |ID|CustomerCountry|CustomerEmail|TotalPrice|DateOfWeek|Date|
              Ответить
          • Сайтов, требующих нормализации, оптимизации и прочей херни - полпроцента. Остальным и так нормально.
            Ответить
            • >Сайтов, требующих нормализации, оптимизации и прочей херни - полпроцента. Остальным и так нормально.

              Сайтов, требующих базы данных - полпроцента. Остальным и так нормально.
              Ответить
          • > За выбор по лайку в OLTP надо выгонять из профессии навсегда

            Удваиваю. За table_full_access надо гнать.

            Сталкивался с похожей задачей. Писал парсеры: https://gist.github.com/kai3341/45cd4f06a1ed346a999629c66a14199e

            Удивительно, что в SQL отсутствует такая простая (для императивных языков) штука, как split. Удивительно, что приходилось изобретать велосипеды

            PS: а что, отформатировать код в читабельном виде религия не позволяет?
            Ответить
            • >> split
              Потому что первая нормальная форма говорит нам что ненужно хранить в поле коллекции чего-либо.

              Но суха теория, мой друг: в postgresql и ms-sql можно хранить XML и JSON. Можно строить по ним индексы, и даже дергать данные через XQuery.

              Вон даже в mysql завезли
              Ответить
              • а че xml-то сразу и че сразу "хранить"? какой-то comma-separated может прийти откуда угодно и пригодиться в неподходящий момент (особенно на фоне того, что далеко не каждый разработчик заднего конца умеет передавать массивы через драйвер его субд)

                regexp_split_to_array, regexp_split_to_table штатно в постгресе делают то, как называются - сплитят строку в массив или setof по паттерну

                в оракле это через жопу, но тоже есть, но учитывая, что массивы/коллекции в оракле - это стыд и позор + контекст переключения sql<->plsql тоже стыд и позор, то изложенный ниже вариант может быть самым "адекватным" и самому аналог писать не стоит:
                select regexp_substr('SMITH,ALLEN,WARD,JONES','[^,]+', 1, level) from dual
                  connect by regexp_substr('SMITH,ALLEN,WARD,JONES', '[^,]+', 1, level) is not null;
                ----------------------
                SMITH
                ALLEN
                WARD
                JONES
                Ответить
                • главное, чтобы поля в CSV запятых не содержали
                  "1,000,000.00","So much money, Dude!"\n\r
                  Ответить
                  • Кстати, а как экранировать кавычки? Так что ли:
                    "Говно ваш \"С++\"","То ли дело \"PHP\""

                    Или на это тоже нет стандарта?
                    Ответить
                    • Клин вышибают клином, кавычки экранируют кавычками, т.е.
                      "Говно ваш ""С++""","То ли дело ""PHP"""
                      -- https://tools.ietf.org/html/rfc4180
                      Ответить
                      • Ясно. Значит, когда для разделения полей используют точку с запятой либо эскейпят кавычки по-другому , нарушают стандарт.
                        Ответить
                        • > нарушают стандарт

                          Этот рфц — скорее рекомендация, чем стандарт. Его в принцепе невозможно соблюдать на 100%, в нём ни слова про юникод, например.
                          Я считаю, что разумно сделать символ разделителя "параметром" этого "стандарта".
                          Ответить
    • А, я понял в чем дело. Автор не знает как хранить много-к-одному, как делать внешний ключ в базе данных, и при этом проектирует базы.

      Это примерно как не знать что такое цикл, и пытаться писать приложения
      Ответить
      • Циклы у твоей мамки, приложил ей к коренному зубу.
        Ответить
      • Я думаю появилась возможность указывать более 1 категории, и лень было менять схему базы.
        Ответить
        • Ну, а нахуй? Чай, на "ModX" не аналоги "Amazon" и "Aliexpress" создают.
          Ответить
    • Можно оптимизировать, если хранить "|3||8||12||43||23|"
      Ответить
      • Всегда так делаю.
        Ответить
      • Вообще, всё не в пример проще: достаточно хранить идентификаторы разделёнными запятой и для поиска использовать такой запрос:

        SELECT `id`, `pagetitle` FROM `modx_site_content` WHERE FIND_IN_SET([id], `categores`);
        Ответить

    Добавить комментарий