Мой способ универсален для всех, кто использует PostgreSQL.
Как я понимаю, ваши способы в принципе не допускают такой операции как UPDATE. Точнее, обновления, при котором изменяется значение, хранимое в поле created_at.
При таком ограничении говорить об универсальности - ну как минимум лукавство.
Для ускорения поиска данных в декларативно секционированной таблице необходима обязательная передача ключа партицирования (p_key) в теле условия запроса. В противном случае поиск будет идти по всем секциям
Почему вы решили, что больше? Я вижу перечисление отдельных факторов, но не вижу, где их соотносят по величине. Тем более не вижу, где повышение плавучести объявляется финальным эффектом. Собственно, чуть выше написано:
При достижении глубины более 6км погружение батискафа резко затормозилось
Затормозилось - да, но не обнулилось же! Тем более - не сменилось на подъём.
А если пользователь, захочет пойти на страницу 3 тогда
А если юзер захочет пойти на предпоследнюю страницу? А шардов много, и записей ещё больше... Вы представляете, какой объём данных предстоит получить, разместить и слить вашему координатору? А если ещё и юзеров много, и все они внезапно захотели пойти на предпоследнюю страницу - причём одновременно? Судя по последним абзацам - немножко представляете. Но что с этим делать, не представляете совсем, ибо надежда на то, что "пользователи делают это редко" - ну несерьёзно, право слово. Впрочем, я тоже не представляю.
Но это как с младшим братом такого случайного шардирования, партиционированием по хэшу. Из-за утраты детерминированности местоположения записи основная цель использования меняется - теперь это распараллеливание обработки. Но для партиционирования хотя бы видны перспективы профита.
PS. Если наличие тега PostgreSQL более-менее оправдано (одна ссылка всё же есть), то тег MS SQL, походу, просто участвует в массовке.
PPS.
Шардинг БД (db sharding) — это метод горизонтального масштабирования, при котором большая база данных разбивается на более мелкие, независимые части (shards), размещаемые на разных физических или виртуальных серверах.
Доводилось ли вам видеть/слышать о шардах в рамках одного инстанса ОС?
Интересно есть ли тепловые машины с турбодетандером, например централизованные кондиционеры больших зданий?
Крайне сомнительно. Высокооборотное прецизионное оборудование плохо подходит для бытового применения, тут потребная квалификация обслуги куда как выше, чем у рядового кондиционерщика. Да и шумное оно.
Понять устройство реляционных БД: что такое таблица, строка, столбец, первичный ключ (уникальный идентификатор записи), внешний ключ (связь с другой таблицей).
В устройстве реляционных БД нет таких терминов как "строка" и "столбец". Это термины/понятия из табличных процессоров, вроде Excel.
В реляционных БД есть записи и поля.
Первичный ключ - это НЕ уникальный идентификатор записи. Это ограничение (CONSTRAINT). А уникальный идентификатор записи - это одна из функций, которую выполняет первичный ключ в силу своих свойств. То же относится и к внешнему ключу.
Пример: в таблице имеется первичный ключ - синтетический автоинкремент или GUID. А уникальная идентификация записи выполняется по значению в поле ИНН или, скажем, в поле номера полиса ОМС.
Ошибка с типами данных – частая причина сломанных запросов
Ничуть не реже ошибки с типом данных являются причиной "просадки производительности". Причём это может быть и архитектурная погрешность - в отличие от "сломанных запросов", где вся вина однозначно лежит на авторе запроса.
Умение посчитать Retention (удержание) или Churn (отток) одним запросом – это классическое тестовое задание на собеседовании.
Это не имеет никакого отношения к SQL. Это специфические для аналитика знания. Дайте специалисту по SQL формулы, и он напишет запрос, даже не подозревая, как называется то, что он получил.
Нужно найти заказ, который не зарегистрировался - это заказ 44.
Прямым SQL-запросом найти отсутствующие значения невозможно, так как из базы нельзя получить значения, которых там нет.
Так, минуточку... вот только-только кто-то русским по белому сказал:
есть список заказов в системе клиента, которые мы ждем: 11, 22, 33, 44, 55
А это, я извиняюсь, ГДЕ? И для вашей системы ЧТО? Если почитать то, что написано далее, то можно сделать вывод, что это не данные, хранящиеся в БД, а параметры, которые передаются в СУБД. И, значит, фраза об отсутствующих данных - она в данном случае вообще ни к месту.
Основной способ для многих СУБД
По-моему, именно основной способ для абсолютно всех СУБД выглядит приблизительно так:
SELECT *
FROM ( SELECT 11 AS zakaz, 'Анна' AS name UNION ALL
SELECT 22 , 'Иван' UNION ALL
SELECT 33 , 'Мария' UNION ALL
SELECT 44 , 'Петр' UNION ALL
SELECT 55 , 'Владимир'
) AS temp;
в PostgreSQL самый простой способ это unnest()
Да? А давайте мы подумаем, что должен сделать Постгресс по вашему коду..
Сначала он должен распарсить и понять текст запроса, включая и ваш фрагмент с кодом создания и последующего парсинга массива. Ну разбор текста запроса - он всегда, его на кривой козе не объехать. Но дальше-то...
Постгресс по вашему тексту должен создать массив и положить в него указанные значения. А потом вызвать функцию, которая разберёт этот массив на отдельные значения и преобразует в набор записей. Вам не кажется, что тут какие-то телодвижения являются немножко лишними?
И абсолютно та же история на всех остальных кодах, где набор значений подаётся в виде CSV или JSON и затем парсится в набор записей. Тогда как код с VALUES / ROW() и приведённый мной выше код - он сразу заставляет СУБД создать набор записей.
Да, вариант с передачей параметров в сериализованной форме с десериализацией в SQL-коде - он имеет право на существование. Во-первых, когда сериализованное значение прибывает именно как единый параметр откуда-то издалека - ну да, заслать одну длинную текстовую строку реально проще, чем массив/коллекцию. Во-вторых, когда список значений, подлежащих передаче в запрос, достаточно объёмный, и его использование в "классической" форме приведёт к нечитаемому и плохо контролируемому по причине большого объёма коду. Но эти случае неплохо было бы озвучить явно, чтобы не создавалось впечатление, что использование десериализации хорошо всегда.
Ну тогда я какой-то неправильный покупатель... не найдя нужный мне товар на привычном месте, я не стану его искать - у меня под боком ещё 4 разных магазина, и минимум в половине из них такой же товар есть. И из тех 4 "резервных" магазинов я посещу минимум пару и доберу что не попалось и что "хочется вотпрямсчас".
Потому я просто спокойно иду и собираю в тележку то, что обычно беру в этом магазине.. если перемещённый товар попадётся на глаза, возьму, а нет, так плакать не буду. А что взял не в гипере, а в другом - ну так это последствия изменения раскладки, которые не обязаны быть положительными. Пусть страдает...
Хотя покупатель, приходящий с магазин со списком - это по определению "покупатель неправильный".
Так вы ж не первую и не вторую статью публикуете. Пора бы уже. Пусть в статье одна, да хотя бы и самая простая, задача разбирается подробно и полностью, а остальные тезисно - уже совсем другой уровень получится. Впрочем, вам, наверное, виднее..
Потребителю это всё пофиг, он ж за пределами. Он поёт про то, что видит.
А я в реальном гипермаркете вижу ежемесячные перемещения - иногда минорные, но раз в пару лет настолько глобальные, что потом месяц привыкаешь искать те же товары в новых местах. Торговая сеть достаточно немелкая, уж аналитики-то у них точно в наличии, и не все джуны. Ан поди ж ты..
Ну очень обидно - вроде хорошее дело делаете, но опять, как говорят некоторые товарищи, стремясь остаться в цензурном пространстве, через "универсальный интерфейс". Сформулировали задачу - кратенько так, без подробностей, зато с красочными дополнительными деталями,- и сразу выдали подходящий SQL-код. Формулы? нету. Подробные объяснения, почему итоговый SQL получился именно таким? и не пахнет. Последовательность решения, отдельные этапы решения, соответствующие трансформация и усложнение SQL? даже в мыслях не было. А по итогу - ну совершенно пустая и ни к чему не применимая статья.
А тем "сотрудникам", которые, ориентируясь на посчитанные в статье показатели, каждый месяц самым радикальным образом меняют местоположение товаров в торговом зале, я бы руки да головы обрывал. Руки - чтобы не делали что не надо, а головы... так они ими всё равно не пользуются. Показатели - они, может, и важное, но не главное. А эффект от факта изменения размещения товаров они пока анализировать не научились.
Что-то вот вчера на работе всплыло, и захотелось спросить.
А какое нынче в мире отношение к использованию иммерсионных жидкостей в разъёме?
Понятно, что иммергированное соединение требует однозначно чистки и нового нанесения геля при любых операциях - это из минусов и потерь. А каковы плюсы? Ну то есть не качественно - понятно, что понизятся и отражение, и затухание,- а (не ржать!) хотя бы качественную оценку изменения количественных показателей.. бы..
Угу. Ну только не обязательно поле (у вас - колонка, но мы не в Экселе же), а выражение. Которое может включать одно или несколько полей, а также одно или несколько выражений от значений полей и констант.
Что забавно - первичный ключ жёстко связан с первичным индексом, а вот между вторичными ключом и индексом никакой связи нет... то есть он может существовать, но не обязан (сейчас любят всё, в том числе и контроль уникальности, сваливать на клиента).
PS. В анализе данных для создания структуры такой ключ называется емнип "кандидат".
У них там что, нет компьютеров общего пользования, в ихних америках, что ли? Или домашних компьютеров, за которыми сидит кто успел - и все под одной учёткой? Или опенспейсов с "готовыми к употреблению" рабочими местами? А если родитель 40 лет от роду ставит ось на комп, купленный для 13-летнего чада, то чей возраст он должен вводить? не, не по логике, а по тексту закона...
Согласен ли ты, что при создании новой not null колонки со значением по умолчанию, значения в строках таблицы не изменяются.
Да, согласен. Изменение метаданных не затрагивает область данных. Я вроде об этом говорил.
А при чтении строк созданных до добавления колонки, значение для колонки возвращается из attmissingval?
И с этим согласен. И об этом я тоже говорил.
я рассуждал с точки зрения потребителя
Ну тогда надо чётко делить - вон там я говорил о внешнем эффекте, а вот тут о технической стороне вопроса. Иначе и возникают подобные непонимания.
Читаю таблицу, получаю одно значение. Меняю метаданные, читаю таблицу ещё раз, получают другое значение.
Вот опять. Читаешь таблицу, и НЕ получаешь поля, о котором говоришь, ибо оно не создано, и его в структуре нет. Меняешь метаданные, создавая поле, читаешь таблицу, и теперь получаешь запись другой структуры, со свежесозданным полем. Это не ДРУГОЕ значение. Потому что твоего "одного значения" - не было, а получение этого "одного значения" - галлюцинация из-за неаккуратной формулировки.
На практике - я не смог обновить attmissingval.
Конечно, это же запрещено. Нет, можно остановить Постгресс, влезть грязными лапами через какой-нить бин-редактор в файл метаданных, поправить значение, снова запустить Постгресс и посмотреть, скушает ли он это изменение и покажет ли теперь изменённое значение. Я, правда, сомневаюсь, и сильно надеюсь, что Постгресс по каким-нибудь внутренним контрольным суммам сумеет обнаружить стороннее изменение и завопит о разрушении данных, но надо проверять.
Блин. Поля НЕ БЫЛО! Ты его только что создал. Если не было поля - не было и значения в этом поле. Вот объясни мне, дураку, как нечто не существующее может ПОМЕНЯТЬСЯ? Поменяться может только существующее значение - некое конкретное или признак отсутствия ака NULL. Было старое значение, стало новое - это называется поменяться. А у тебя значение ПРИСВОЕНО. Что называется, "с нуля". Раньше не было, теперь есть.
И это косвенно подтверждается тем, что значение, записанное в attmissingval, не изменяется при изменении DEFAULT. Потому что либо запись существовала на момент создания поля, и тогда ему было присвоено начальное DEFAULT, но оно не записано в тело записи, и его надо брать из attmissingval, либо запись не существовала и была создана позднее - тогда в тело данных записи сразу было записано значение этого поля, взятое из column_default. И для записи, которая существовала, при любом её изменении будет записано новое состояние этой записи, на сей раз уже с внесённым туда полем и его значением, взятым из attmissingval. И уже по телу записи невозможно определить, была ли запись на момент создания поля, или была вставлена позже.
Ну да ну да. Вот то есть сеть сделана по уму, есть даже сервер удалённой загрузки, и коммутатор где-то имеется на этот класс, причём явно не на ученическом столе, а маршрутизатор (кстати, ROAS) находится посередь класса и включен в клиентскую розетку. При том, что ему (как и коммутатору) в компьютерном классе возле рабочего места вообще нечего делать - он должен находится как минимум в той точке, куда выведены все провода и где стоИт коммутатор..
Я бы сказал, что автору надо бы принять пару таблеточек нетрындина.
ИИ ж не думает, ему тупо нечем. Ему никто не сказал, а сам он не в жисть не догадается, что NOT NULL в описании поля - это просто синтаксический сахар для CONSTRAINT constraint_name CHECK (column_name IS NOT NULL). Вот и галлюцинирует.
Как я понимаю, ваши способы в принципе не допускают такой операции как UPDATE. Точнее, обновления, при котором изменяется значение, хранимое в поле created_at.
При таком ограничении говорить об универсальности - ну как минимум лукавство.
А почему не используете Partition Pruning?
Насосы не требуются, достаточно разместить вход-выход на разной высоте (в идеале - вообще вертикально), и нагрев воды обеспечит тягу.
Но представьте себе степень усложнения конструкции..
Да, кстати, в этом случае такие трубки ещё обеспечат и реактивную тягу... и, если не озаботиться, то в направлении дна.
Почему вы решили, что больше? Я вижу перечисление отдельных факторов, но не вижу, где их соотносят по величине. Тем более не вижу, где повышение плавучести объявляется финальным эффектом. Собственно, чуть выше написано:
Затормозилось - да, но не обнулилось же! Тем более - не сменилось на подъём.
А если юзер захочет пойти на предпоследнюю страницу? А шардов много, и записей ещё больше... Вы представляете, какой объём данных предстоит получить, разместить и слить вашему координатору? А если ещё и юзеров много, и все они внезапно захотели пойти на предпоследнюю страницу - причём одновременно? Судя по последним абзацам - немножко представляете. Но что с этим делать, не представляете совсем, ибо надежда на то, что "пользователи делают это редко" - ну несерьёзно, право слово. Впрочем, я тоже не представляю.
Но это как с младшим братом такого случайного шардирования, партиционированием по хэшу. Из-за утраты детерминированности местоположения записи основная цель использования меняется - теперь это распараллеливание обработки. Но для партиционирования хотя бы видны перспективы профита.
PS. Если наличие тега PostgreSQL более-менее оправдано (одна ссылка всё же есть), то тег MS SQL, походу, просто участвует в массовке.
PPS.
Доводилось ли вам видеть/слышать о шардах в рамках одного инстанса ОС?
Крайне сомнительно. Высокооборотное прецизионное оборудование плохо подходит для бытового применения, тут потребная квалификация обслуги куда как выше, чем у рядового кондиционерщика. Да и шумное оно.
В устройстве реляционных БД нет таких терминов как "строка" и "столбец". Это термины/понятия из табличных процессоров, вроде Excel.
В реляционных БД есть записи и поля.
Первичный ключ - это НЕ уникальный идентификатор записи. Это ограничение (CONSTRAINT). А уникальный идентификатор записи - это одна из функций, которую выполняет первичный ключ в силу своих свойств. То же относится и к внешнему ключу.
Пример: в таблице имеется первичный ключ - синтетический автоинкремент или GUID. А уникальная идентификация записи выполняется по значению в поле ИНН или, скажем, в поле номера полиса ОМС.
Ничуть не реже ошибки с типом данных являются причиной "просадки производительности". Причём это может быть и архитектурная погрешность - в отличие от "сломанных запросов", где вся вина однозначно лежит на авторе запроса.
Это не имеет никакого отношения к SQL. Это специфические для аналитика знания. Дайте специалисту по SQL формулы, и он напишет запрос, даже не подозревая, как называется то, что он получил.
Что-то я совсем не понял преамбулы. Вы пишете:
Так, минуточку... вот только-только кто-то русским по белому сказал:
А это, я извиняюсь, ГДЕ? И для вашей системы ЧТО? Если почитать то, что написано далее, то можно сделать вывод, что это не данные, хранящиеся в БД, а параметры, которые передаются в СУБД. И, значит, фраза об отсутствующих данных - она в данном случае вообще ни к месту.
По-моему, именно основной способ для абсолютно всех СУБД выглядит приблизительно так:
Да? А давайте мы подумаем, что должен сделать Постгресс по вашему коду..
Сначала он должен распарсить и понять текст запроса, включая и ваш фрагмент с кодом создания и последующего парсинга массива. Ну разбор текста запроса - он всегда, его на кривой козе не объехать. Но дальше-то...
Постгресс по вашему тексту должен создать массив и положить в него указанные значения. А потом вызвать функцию, которая разберёт этот массив на отдельные значения и преобразует в набор записей. Вам не кажется, что тут какие-то телодвижения являются немножко лишними?
И абсолютно та же история на всех остальных кодах, где набор значений подаётся в виде CSV или JSON и затем парсится в набор записей. Тогда как код с VALUES / ROW() и приведённый мной выше код - он сразу заставляет СУБД создать набор записей.
Да, вариант с передачей параметров в сериализованной форме с десериализацией в SQL-коде - он имеет право на существование. Во-первых, когда сериализованное значение прибывает именно как единый параметр откуда-то издалека - ну да, заслать одну длинную текстовую строку реально проще, чем массив/коллекцию. Во-вторых, когда список значений, подлежащих передаче в запрос, достаточно объёмный, и его использование в "классической" форме приведёт к нечитаемому и плохо контролируемому по причине большого объёма коду. Но эти случае неплохо было бы озвучить явно, чтобы не создавалось впечатление, что использование десериализации хорошо всегда.
Ну тогда я какой-то неправильный покупатель... не найдя нужный мне товар на привычном месте, я не стану его искать - у меня под боком ещё 4 разных магазина, и минимум в половине из них такой же товар есть. И из тех 4 "резервных" магазинов я посещу минимум пару и доберу что не попалось и что "хочется вотпрямсчас".
Потому я просто спокойно иду и собираю в тележку то, что обычно беру в этом магазине.. если перемещённый товар попадётся на глаза, возьму, а нет, так плакать не буду. А что взял не в гипере, а в другом - ну так это последствия изменения раскладки, которые не обязаны быть положительными. Пусть страдает...
Хотя покупатель, приходящий с магазин со списком - это по определению "покупатель неправильный".
Так вы ж не первую и не вторую статью публикуете. Пора бы уже. Пусть в статье одна, да хотя бы и самая простая, задача разбирается подробно и полностью, а остальные тезисно - уже совсем другой уровень получится. Впрочем, вам, наверное, виднее..
Потребителю это всё пофиг, он ж за пределами. Он поёт про то, что видит.
А я в реальном гипермаркете вижу ежемесячные перемещения - иногда минорные, но раз в пару лет настолько глобальные, что потом месяц привыкаешь искать те же товары в новых местах. Торговая сеть достаточно немелкая, уж аналитики-то у них точно в наличии, и не все джуны. Ан поди ж ты..
Ну очень обидно - вроде хорошее дело делаете, но опять, как говорят некоторые товарищи, стремясь остаться в цензурном пространстве, через "универсальный интерфейс". Сформулировали задачу - кратенько так, без подробностей, зато с красочными дополнительными деталями,- и сразу выдали подходящий SQL-код. Формулы? нету. Подробные объяснения, почему итоговый SQL получился именно таким? и не пахнет. Последовательность решения, отдельные этапы решения, соответствующие трансформация и усложнение SQL? даже в мыслях не было. А по итогу - ну совершенно пустая и ни к чему не применимая статья.
А тем "сотрудникам", которые, ориентируясь на посчитанные в статье показатели, каждый месяц самым радикальным образом меняют местоположение товаров в торговом зале, я бы руки да головы обрывал. Руки - чтобы не делали что не надо, а головы... так они ими всё равно не пользуются. Показатели - они, может, и важное, но не главное. А эффект от факта изменения размещения товаров они пока анализировать не научились.
Что-то вот вчера на работе всплыло, и захотелось спросить.
А какое нынче в мире отношение к использованию иммерсионных жидкостей в разъёме?
Понятно, что иммергированное соединение требует однозначно чистки и нового нанесения геля при любых операциях - это из минусов и потерь. А каковы плюсы? Ну то есть не качественно - понятно, что понизятся и отражение, и затухание,- а (не ржать!) хотя бы качественную оценку изменения количественных показателей.. бы..
Угу. Ну только не обязательно поле (у вас - колонка, но мы не в Экселе же), а выражение. Которое может включать одно или несколько полей, а также одно или несколько выражений от значений полей и констант.
Что забавно - первичный ключ жёстко связан с первичным индексом, а вот между вторичными ключом и индексом никакой связи нет... то есть он может существовать, но не обязан (сейчас любят всё, в том числе и контроль уникальности, сваливать на клиента).
PS. В анализе данных для создания структуры такой ключ называется емнип "кандидат".
Ну тут как раз всё просто - совпадают только вторая и последняя буквы, а всё остальное различается.
В некоторых культурах это уже 14 лет. А 13 началось в 12 лет и 1 секунду.
У них там что, нет компьютеров общего пользования, в ихних америках, что ли? Или домашних компьютеров, за которыми сидит кто успел - и все под одной учёткой? Или опенспейсов с "готовыми к употреблению" рабочими местами? А если родитель 40 лет от роду ставит ось на комп, купленный для 13-летнего чада, то чей возраст он должен вводить? не, не по логике, а по тексту закона...
Да, согласен. Изменение метаданных не затрагивает область данных. Я вроде об этом говорил.
И с этим согласен. И об этом я тоже говорил.
Ну тогда надо чётко делить - вон там я говорил о внешнем эффекте, а вот тут о технической стороне вопроса. Иначе и возникают подобные непонимания.
Вот опять. Читаешь таблицу, и НЕ получаешь поля, о котором говоришь, ибо оно не создано, и его в структуре нет. Меняешь метаданные, создавая поле, читаешь таблицу, и теперь получаешь запись другой структуры, со свежесозданным полем. Это не ДРУГОЕ значение. Потому что твоего "одного значения" - не было, а получение этого "одного значения" - галлюцинация из-за неаккуратной формулировки.
Конечно, это же запрещено. Нет, можно остановить Постгресс, влезть грязными лапами через какой-нить бин-редактор в файл метаданных, поправить значение, снова запустить Постгресс и посмотреть, скушает ли он это изменение и покажет ли теперь изменённое значение. Я, правда, сомневаюсь, и сильно надеюсь, что Постгресс по каким-нибудь внутренним контрольным суммам сумеет обнаружить стороннее изменение и завопит о разрушении данных, но надо проверять.
Блин. Поля НЕ БЫЛО! Ты его только что создал. Если не было поля - не было и значения в этом поле. Вот объясни мне, дураку, как нечто не существующее может ПОМЕНЯТЬСЯ? Поменяться может только существующее значение - некое конкретное или признак отсутствия ака NULL. Было старое значение, стало новое - это называется поменяться. А у тебя значение ПРИСВОЕНО. Что называется, "с нуля". Раньше не было, теперь есть.
И это косвенно подтверждается тем, что значение, записанное в attmissingval, не изменяется при изменении DEFAULT. Потому что либо запись существовала на момент создания поля, и тогда ему было присвоено начальное DEFAULT, но оно не записано в тело записи, и его надо брать из attmissingval, либо запись не существовала и была создана позднее - тогда в тело данных записи сразу было записано значение этого поля, взятое из column_default. И для записи, которая существовала, при любом её изменении будет записано новое состояние этой записи, на сей раз уже с внесённым туда полем и его значением, взятым из attmissingval. И уже по телу записи невозможно определить, была ли запись на момент создания поля, или была вставлена позже.
Ну да ну да. Вот то есть сеть сделана по уму, есть даже сервер удалённой загрузки, и коммутатор где-то имеется на этот класс, причём явно не на ученическом столе, а маршрутизатор (кстати, ROAS) находится посередь класса и включен в клиентскую розетку. При том, что ему (как и коммутатору) в компьютерном классе возле рабочего места вообще нечего делать - он должен находится как минимум в той точке, куда выведены все провода и где стоИт коммутатор..
Я бы сказал, что автору надо бы принять пару таблеточек нетрындина.
ИИ ж не думает, ему тупо нечем. Ему никто не сказал, а сам он не в жисть не догадается, что
NOT NULLв описании поля - это просто синтаксический сахар дляCONSTRAINT constraint_name CHECK (column_name IS NOT NULL). Вот и галлюцинирует.