Pull to refresh

Comments 382

Большинство из этого верно, но как всегда на почти каждый пункт существуют контрпримеры. Иначе бы нам, DBA, не платили бы)

Конечно есть, но в каждом конкретном случае исключение должно быть оправдано и аргументировано.

Вот кстати, мотивации иногда в этом списке не хватает. Некоторые советы правда очевидны, но некоторые вовсе нет. Один пример - что значит не используйте UNION? Этож почти тоже самое что не используйте where, а то будет медленно :) Более осмысленно было бы порекомендовать что-то на замену.

Про UNION дан ответ почему в п.30. В данной публикации не было цели прям всё разжевать, а дать выжимку из обобщенного опыта как лучше делать (где-то раскрыто почему, а где-то нет-значит можно легко нагуглить или провести тест самостоятельно)

Будто просто пропало желание расписывать пояснения, в некоторых случаях достаточно было одной строки и вопросов нет

Ок, по просьбе трудящихся тогда просто: "Про UNION дан ответ почему в п.30"

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

SELECT SomeData FROM Table1 WHERE ...
UNION
SELECT SomeData FROM Table2 WHERE ...

Необходимо использовать конструкцию вида:

;WITH CTE AS (
  SELECT SomeData FROM Table1 WHERE ...
  UNION ALL
  SELECT SomeData FROM Table1 WHERE ... )
SELECT DISTINCT SomeData FROM CTE
-- или
SELECT SomeData FROM CTE GROUP BY SomeData

Прочие варианты, например с FULL JOIN, и все равно требующие в итоге DISTINCT или GROUP BY опускаю.

Перечитайте весь п.30-там такого не написано, что Вы написали.

Цитирую:

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

Написано "не используйте". Никаких исключений не указано.

Обратите внимание, что расписано почему.

При этом даже расписано неправильно. Потому что, если объединяемые UNION наборы данных уже одинаково отсортированы, то не будет ни того, ни другого.

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

Даже формулировка

выполнить сортировку или хэширование результирующего набора

строго говоря, не верна. Так как UNION только хеши считает для результирующего набора данных, а сортирует не результирующий набор данных, а каждый из объединяемых наборов данных, выполняя затем слияние Merge Join (Union)

Тем не менее, union тяжеловат сам по себе. И если есть альтернативы, а они есть, то лучше ими воспользоваться.

Я же доказал уже, что есть запросы, на которых нет никакой разницы, кроме хуже читаемого кода. Значит Ваше утверждение уже не верно, раз найдены исключения, его опровергающие.

select 1 показывает, что проблем с производительностью СУБД нет. Значит, все остальные рекомендации про оптимизацию являются неверными раз найдены исключения, опровергающие это.

Вы не могли бы все же оставаться профессионалом и не заниматься демагогией подменяя понятия?

Приведены статистики и планы запросов с UNION и без него, строго по Вашей рекомендации с вложенным запросом и GROUP BY. И они ничем не отличаются. Как может быть что-то "тяжелей" при одинаковом весе?

Жаль, что не смог Вас убедить. Кстати, CTE тоже лучше на лево и направо не раскидываться особенно если таблицы-участницы большие. Но опять же понятие "большие" относительно.

Жаль, что не смог Вас убедить.

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

Кстати, CTE тоже лучше на лево и направо не раскидываться особенно если таблицы-участницы большие.

Если из CTE все равно используются записи только один раз и объединение по равенству, то эффективней даже позволить оптимизатору построить HASH индекс по CTE (worktable) на лету, чем создавать объект в БД и его индексировать. Не говоря уже о случаях синтаксического сахара, когда оптимизатор сам разворачивает CTE без использования worktable.

Ну не бывает в SQL что-то лучше или хуже всегда. То что лучше в одном случае, может оказаться хуже в другом.

Мандарины в голове уже.

С Новым Годом!

Спасибо! Вас так же с наступающим Новым Годом! Успехов везде и крепкого здоровья.

Можно добавить отдельными запросами во временную таблицу и потом с этой таблицей сделать либо group by, либо distinct-смотря сколько полей нужно сделать уникальными. Если 1-3 поля-то group by, а если больше, то distinct (про distinct говорится в п.12)

Через временную таблицу это точно будет менее эффективно, если такой список уникальных записей нужно вернуть клиенту.

Более предсказуемо и невсегда медленнее union.

Но Вы его запрещаете использовать. У меня когнитивный диссонанс )))

Лично я не запрещаю, а рекомендую. Это раз. А во-вторых, пока специалист не обжёгся на конкретном сценарии да ещё и со своим опытом, его очень сложно переубедить. Потому если мои аргументы Вас не переубедили и мы не пересекаемся по проекту, то конечно решение как делать остаётся за Вами и Вашей командой.

Вы, фактически, только что сами указали, что рекомендация архитектора БД "не используйте UNION" является запретом на его использование.

мои аргументы Вас не переубедили

Стоп. Какие аргументы? Если Вы про

должен выполнить сортировку или хэширование результирующего набора перед его возвращением

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

или можно сделать как Вы написали выше с CTE, но без CTE, а просто в подзапросе через union all, а снаружи либо group by, либо distinct согласно п.12

Вариант с UNION и вариант с подзапросом и GROUP BY приводят к одному и тому же:

(3113 rows affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Invoice'. Scan count 1, logical reads 5397, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'FactLoad'. Scan count 1, logical reads 6516, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 63 ms,  elapsed time = 57 ms.

или 

(3113 rows affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Invoice'. Scan count 1, logical reads 5397, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'FactLoad'. Scan count 1, logical reads 6516, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 63 ms,  elapsed time = 58 ms.

Вопрос то был в другом. Почему нельзя использовать UNION?

Оптимизатор умный, но невсегда так будет везти.

А при чем эта декларация очевидности? Я разве утверждал, что бывает "золотой молоток"? Разбирается конкретный пример и не вижу аргументов, почему в нем "не рекомендуется" использовать UNION.

Если Вы про количество записей, то могу увеличить период с одного месяца до начала года. Но планы запросов все равно остаются одинаковыми.

4. явно нуждается в пояснении

5. Странная рекомендация. Ну понятно (надеюсь всем), что по индексированным полям обычно (кстати не в 100% но если не брать в расчёт затраты времени на индексирование то близко к 100%) фильтр выполняется быстрее. Вот только:

а. Всё не проиндексируешь - конечно можно но "цена" будет несоизмеримо более высокой, чем профит, а уж как запись будет проседать!

б. Условия фильтрации не часто определяются исключительно индексированными полями - чаще бизнес-логикой - и тут уже никуда не деться

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

  1. пункт нуждается в пояснениях насёт ветвления кода

  2. пункт - плохо иллюстрирующий пример - тут бы что-то более конкретное и пактичное (менее абстрактное) и полностью определённое

  1. Почти та же пустая рекомендация, что и 5. пункт. Но тут явно нужны пояснения - чем обусловлен такой порядок. Если говорить про MS SQL Server то, насколько я знаю, он уже давно научился сам правильно определять прядок фильтрации, не звисимо от порядка следования условий в SQL запросе. Вот другие СУБД да - не все так умеют. Иля я не правильно понял о каком порядке идёт речь?

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

  2. хотелось бы пояснений для данной рекомендации - почему так?

  1. Примерчики бы

  1. Спорная рекомендация. Union достаточно частый оператор - и хорошая альтернатива менее прризводительным соединением. Но обычно да - используется "Union all" - Вы против уникального юниона или против всех?

  2. Тоже очень спорная рекомендация. Зачастую проверки делаются в конце транзакции - и они влияют на её успех. Но, конечно, всё что можно проверить до транзакции надо проверить до. Но опять же - зачастую для целостности данных нужно соблюсти повторяемость чтения - чтобы, условно, к концу транзакции то, что было прочитано в начале соответствовало фиксируемой транзакции в её конце. И вот тут большинство (если не все) транзакционные СУБД сильно пасуют по своему функционалу!

  1. пункт нуждается в пояснениях

  1. пункт нуждается в пояснениях

  1. Сложный и важный пункт. Явно не хватает примеров и альтернативных решений

Это не столько чисто мои рекомендации, сколько объединение рекомендаций комитетов по SQL из разных компаний в MS SQL, проверенные временем. Большинство пунктов да, я и предложил.

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

Здесь написано очень просто и понятно. Например, ветвление кода: IF-ELSE как один из вариантов реализации ветвления кода. Аналогично по остальным пунктам. Где нетривиально были даны примеры кода.

Для Вас возможно, потому что не понимаете тривиальных вещей.

Тем кто всё понимает - рекомендации не нужны

Всё знать, а тем более всё понимать невозможно. Здесь же написано лаконично и просто о нетривиальном в том числе

По п.6 мне тож не хватает пояснений.

В том же Firebird, если не ошибаюсь, IN самой СУБД "под капотом" заменяется на череду OR перед выполнением запроса. И в таком случае единственная польза от данной рекомендации: удобство восприятия и меньший риск сломать запрос, добавив AND и забыв при этом заключить OR условия в общие скобки.

"под капотом" заменяется на череду OR

Кстати, исправили в FB 5.0, чтобы для каждого значения IN не открывать заново процесс сканирования индекса.

Благодарю за информацию, прошу дать ссылки на источник, чтобы ознакомиться.

Спасибо! Как-то они запоздали с некоторыми введениями, особенно в части merge. И теперь понятно откуда фраза "частичные индексы")

Т е под капотом все что в IN он кладет во временную таблицу (список) и сравнивает с ним как было рекомендовано в публикации в ч.7

Если в SQL Server нет этой оптимизации, значит, каждый элемент IN начинает поиск с корня индекса. Опять же, если положить во временную таблицу, то неизвестно, какую стратегию выберет оптимизатор для джойна с ней. Если LOOP JOIN, то выйдет то же самое. А MERGE может быть не выбран по каким-то соображениям.

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

Это вам нужно перед каждым join указывать его стратегию (loop/hash/merge), а после каждой таблицы - with (index (AAA))

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

В целом со всем согласен, но есть пара моментов

DROP TABLE IF EXISTS перед её созданием

В ad-hoc скриптах может быть удобно, но в разработке это все-таки скорее антипаттерн. В хранимке такой код свою таблицу дропнуть никогда не сможет - она еще не создана. А распоряжаться внешним объектом неизвестного для текущей области видимости назначения он не имеет права - хп ничего про тот объект не знает, это не ее зона ответственности. Полезного этот фрагмент точно ничего не сделает, а навредить и сильно запутать поиск причины проблемы может.

пример
CREATE PROC dbo.level_three
AS
BEGIN
    SELECT 'level_three' AS [level_three], OBJECT_ID('tempdb..#aaa', 'U') obj_id, * FROM #aaa
END;
GO

CREATE PROC dbo.level_two
AS
BEGIN
    SELECT 'level_two' AS [level_two], OBJECT_ID('tempdb..#aaa', 'U') obj_id

    DROP TABLE IF EXISTS #aaa;

    CREATE TABLE #aaa (a VARCHAR(10), b FLOAT);
    INSERT #aaa (a, b) VALUES ('22', 3.14);

    SELECT 'level_two' AS [level_two], OBJECT_ID('tempdb..#aaa', 'U') obj_id

    EXEC dbo.level_three;
END;
GO

CREATE PROC dbo.level_one
AS
BEGIN
    CREATE TABLE #aaa (a INT, b VARCHAR(10));

    INSERT #aaa (a, b) VALUES (1, 'b');

    SELECT 'level_one' AS [level_one], OBJECT_ID('tempdb..#aaa', 'U') obj_id

    EXEC dbo.level_two;

    SELECT 'level_one' AS [level_one], * FROM #aaa;
END;
GO

EXEC dbo.level_one;
GO

DROP PROC IF EXISTS dbo.level_one;
GO

DROP PROC IF EXISTS dbo.level_two;
GO

DROP PROC IF EXISTS dbo.level_three;
GO

Причем если закомментить дроп, то код вполне себе сможет выполниться и каждая область видимости будет работать со своим объектом. Хотя, честно признаюсь, до последнего времени был убежден, что без дропа будет ошибка вида "объект с таким именем уже существует" и вроде как так и работало и из-за этого, в том числе, и придумали дропать, если вдруг кто мешает текущему коду выполниться (что довольно самонадеянно). Может я что напутал когда-то давно, может упустил изменение, но суть в том, что дропать то, чего еще текущий контекст не создал точно не стоит.

А ещё лучше <запрос> выполнить до COALESCE

Предложил бы сразу рекомендацию и переписать, не предлагать то, что приносит в код новые потенциальные проблемы. Так-то и NULL может быть нужен, и не трогать переменную, если ничего не нашлось - по ситуации; рекомендация довольно абстрактная. И в SELECT-SET, и в SET-SELECT много чего нужно иметь ввиду и понимать, что ты делаешь.

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

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

По остальным пунктам субъективно. Если нужен null, пишут по другому, а вообще лучше проектировать БД без null и значения получать конкретные. Например, я ввожу в справочник нулевой идентификатор, чтобы не использовать внешнее соединение. Null нужен больше в академических целях, а в практических в большинстве случаев нужно конкретное значение в итоге, но правильно обработать null нужно, о чем и написано выше.

чтобы при проверке увидеть есть ли пересечение в именах локальных временных таблицах

А как кто-то или что-то это увидит? И "проверки" ведь нет, есть вышибание табуретки из под ног вложенных и внешнего батчей. Таблица спокойно подменится, понятной ошибки не будет ни в какой момент.

Условный THROW IF EXISTS - это да, это была бы проверка, которая вовремя бы дала понять разработчику, что есть пересечение по именованию.

Как раз при вышибании табуретки сразу будет видна ошибка.

Так не будет же, о чем и речь. Если структура будет создана несовместимая, то ошибка будет абсолютно непонятная и в месте никак не связанном с точкой "проверки" через DROP IF EXISTS. А если структура окажется совместимой, то код ниже по уровням вложенности молча и с удовольствием пойдет лопатить вообще не те данные. Этот DROP - почти то же самое, что WHILE @@TRANCOUNT > 0 COMMIT потому что мне тут чужая транзакция не нужна. Мне тут ваши внешние таблицы не нужны - это точно не проверка и точно распоряжение объектом, про который текущий контекст ничего не знает.

Нужно правильно тестирование делать.

А неправильно - не делать. Понятно.

13 При проектировании стараться делать так, чтобы первичные ключи и
кластерные индексы (да и некластерные тоже) наполнялись значениями не в
одном направлении (т е чтобы значения монотонно не возрастали и не
убывали). Случайное значение — плохо для перфоманса (хотя в случае
обновления 100% этого результата не достичь, но обычно PK не обновляют).
Также плохо монотонное возрастание/убывание значений ключей и индексов.

Несколько раз пытался понять, и не понял.

Auto increment PK ID - плохо?

GUID - тоже плохо?

Инкремент конечно плохо, т к будет конкуренция.

Нет, потому что инкремент идёт в автономной транзакции

Тут видимо речь о записи в одну и ту же листовую страницу индекса. Если 50 параллельных коннектов одновременно записали значения ключа 100, 101, ... 149, они попадут в один лист индекса. А если просто рандомные значения ключа, они распылятся по разным страницам. С другой стороны, в первом случае придётся записать 1 страницу на диск, собрав все данные последовательно, а во втором случае - записать 50 страниц. Неизвестно, что хуже.

Это да. Но GUID рыхлит таблицу, увеличивая фрагментацию, плюс он много длиннее как primary key

Возможно, это было верно для старой парадигмы "быстрый cpu - медленный сторадж". А когда на сторажде 1M IOPS, у CPU 96 ядер, то может и пусть пишут больше страниц, лишь бы между ядрами было меньше синхронизации.

Конечно, это для сценария "100500 потоков параллельно пишут каждый свою 1 запись". Для сценария "10 потоков, и каждый записал 10к записей" инкрементальный ключ всегда выгоднее.

Спасибо, что раскрыли п.13-да: и случайно - это плохо для деревьев, и последовательно - это плохо для конкуренции последней записи. Потому совет рабочий, а вот как реализовать зависит от нагрузки и чтений. Может нужно много писать и редко читать-ну так bulk insert и не мучаться. Может пишет только один сервис-тогда вообще инкремент и всё.

Фигасе, у вас там в ентерпрайзе 1М IOPS и storage, который быстрее CPU...

А по факту вопроса, ответа так и не увидел.

Опять же с моей колокольни (авто)инкрементные индексы обычно и являлись PK и/или clustered индексами. А тут теперь и так плохо, и эдак плохо. А как хорошо не говорите.

Чтобы UUID не рыхлил индексы можно использовать UUID V6.

Правильно. Хипы наше всё. Нужны случайно монотонные PK. Интересно, автор знает почему эти рекомендации существуют?

Можно сделать так, чтобы было чередование возрастания/убывания значений. Например, через группу последовательностей: одна последовательность для каждого типа записей. Если просто значения будут монотонно возрастать/убывать, то будет конкуренция за последнюю страницу при параллельных вставках.

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

А если монотонно возрастающий, то добро пожаловать в конкуренцию последней записи при параллельных вставках. Никому не пожелаю в высоко нагруженных системах.

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

Тестировали и замеряли или просто прочитали распространенную рекомендацию?

Нет, и то и другое плохо. В п.13 описан идеальный вариант, но полностью не достижимый. Однако, как именно реализовать и на сколько близко или далеко подойти к рекомендации в п.13 зависит от требований к системе.

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

Индекс используется не только для уникальности, но и для сортировки значений.
Совет "индекс по хешу" нужно принимать с оговоркой использования.

Спасибо за поправку, добавлю в пункт

п. 45 - в чем проблема с SELECT INTO ? почему не использовать?

п. 50 - кем запрещено и почему?

да и в принципе по тексту, надо бы как то подтверждать свои утверждения, а не ставить их в ультимативной форме

Если в пункте объяснено почему, значит искать и проверять дольше, чем 5-10 мин. Если дан пример-аналогично. Если не расписано почему/нет примера, значит можно самостоятельно это сделать менее, чем за те же 5-10 мин. У публикации не стояла цель все пункты разжевать. Конкретно по п.45 ответ очевиден-если нет, советую поучить всё-таки матчасть MS SQL (правда-очень просто). Но для разовых скриптов может и норм. Для п.50 аналогично.

Хорошо, если я пишу такую конструкцию:

IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL
	DROP TABLE #tempTable;

SELECT
<fields>
INTO #tempTable
FROM dbo.table
where ...

<do something with #tempTable>

IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL
	DROP TABLE #tempTable;

<do something else>

в чем конкретно здесь будет проблема?
и да, по матчасти, это оффициально декларируемые возможности SQL Server, они не запрещены.
может быть всё же дело в контексте - какую БД и для чего мы разрабатываем, что храним, и как используем? то что верно для транзакционных баз не всегда верно для DWH

В чем разница создавать таблицу SELECT INTO или определить её заранее? Много что есть в T-SQL как и в других языках программирования, но не все стоит использовать на постоянной основе и тем более при многократных вызовах.

В скорости вставки.
SELECT INTO гораздо быстрей если вы накладываете эксклюзивную блокировкиу на читающую таблицу

Да Вы что. А если надо кластерный индекс определить по временной таблице? А статистику? А Вы всегда сможете контролировать нужные типы и их ограничения без четкого определения временной таблицы? Рисков слишком много, чтобы вот так использовать SELECT INTO. На самом деле очень спорный вопрос, что select into быстрее, т к оценивается только создание и наполнение временной таблицы, но не оценивается вся работа с ней.

Если в этой таблице создавать еще кластерный индекс, то выигрыш через SELECT INTO будет еще на один порядок больше чем через таблицу с кластерным индексом

В любом случае, у нас есть кейс, в котором испльзование SELECT INTO предпочтительней исходя из времени.
Т.е у нас появляются варианты когда мы хотим использовать один или другой подход. И это то место, где универсализм неуместен

Кластерный индекс лучше создавать до вставки данных во временную таблицу, а некластерный после (см п.38 и там же ссыль на исследование). Универсализм это как раз SELECT INTO и быстрее он работает, потому что много чего не делает, как если бы сначала точно определяли сигнатуру временной таблицы. И это "быстрее" суммарно станет медленнее, если оценить время не только создание и наполнение таблицы, но все операции с ней. Тоже не раз проверено и не на одной БД.


Ну это ведь неправда...
Настолько неправда, что пришлось быстро тест подготовить.

Имеем не самую большую таблицу(примерно 400 млн записей):

SELECT count(*) FROM [dbo].[SourceProviders] WITH (NOLOCK) 	
--393222888  

ну и сам тест:

CREATE TABLE tempdb.dbo.SourceProviders1 ([StagingProviderID] [bigint] CONSTRAINT [PK_SourceProviders1] PRIMARY KEY CLUSTERED ([StagingProviderID] ASC))
GO

SET STATISTICS TIME ON

PRINT '--1 pre-created table --'

INSERT INTO tempdb.dbo.SourceProviders1
SELECT [StagingProviderID]
FROM [dbo].[SourceProviders]
GO

PRINT '-- END 1 --'
PRINT '--2 Select Into table --'

SELECT [StagingProviderID]
INTO tempdb.dbo.SourceProviders2
FROM [dbo].[SourceProviders] WITH (TABLOCK)
GO

CREATE CLUSTERED INDEX IX_SourceProviders2_SourceProviders ON tempdb.dbo.SourceProviders2 ([StagingProviderID] ASC)
	WITH (
			MAXDOP = 8
			,sort_in_tempdb = ON
			)
GO

PRINT '-- END 2 --'

Результат:

--1 pre-created table --

SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.

SQL Server Execution Times:
CPU time = 367485 ms, elapsed time = 496638 ms.

(393222888 rows affected)
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 1 ms.
-- END 1 --

SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
--2 Select Into table --

SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.

SQL Server Execution Times:
CPU time = 200172 ms, elapsed time = 89096 ms.

(393222888 rows affected)
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.

SQL Server Execution Times:
CPU time = 406719 ms, elapsed time = 82332 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
-- END 2 --

SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.

Completion time: 2023-12-11T14:51:57.2439988-05:00

Итого 500000 ms против примерно 200000 ms

Опять же Вы провели тест только на создание и наполнение таблицы.

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

Порой сложно объяснить, если сам считаю, что просто написал. Т е не знаю как ещё проще/лучше написать. Это и не хорошо, и не плохо.

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

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

Локальная временная таблица, созданная в хранимой процедуре, удаляется автоматически по завершении хранимой процедуры. На таблицу могут ссылаться любые вложенные хранимые процедуры, выполняемые хранимой процедурой, создавшей таблицу. Процесс, вызвавший хранимую процедуру, создавшую таблицу, не может ссылаться на таблицу.
Все остальные локальные временные таблицы автоматически удаляются в конце текущего сеанса.
https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql?view=sql-server-ver16#temporary-tables

и сразу отвечу на коммент ниже (ибо ограничен):
вы так говорите, будто рекомпиляция это всегда что-то плохое) таки бывают случаи когда это полезно

На самом деле холиварная тема, но в большинстве случаев важен именно отклик системы, а не что там ресурсы долго держит. Даже ОС сейчас пошли не "жадные", т е не спешат сразу отдавать тот объем ОЗУ, который уже не нужен закрытым сервисам/сессиям/потокам. Т е зная и даже сталкиваясь с такими ситуациями все равно рекомендация остаётся в силе. Даже со стороны DBA. Быстродействие системы важнее.

По поводу временных таблиц я тоже писал

https://habr.com/p/723278/

Однако там в комментах нашли очень интересный пример, где сиквель сходит с ума

Рекомпиляции на постоянной основе плохо, т к не решена причина проблемы, из-за которой эти рекомпиляции понадобилась.

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

IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL

лучше заменить на DROP TABLE IF EXISTS tbl1, tbl2, ...;

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

6. Стараться в условиях не использовать оператор OR, а заменить его на IN или разбить на разные команды с помощью ветвления кода.
Это вы никогда не попадали на эти ошибки видно в операторе IN

Error 8623:

The query processor ran out of internal resources and could not produce a query plan. This is a rare event and only expected for extremely complex queries or queries that reference a very large number of tables or partitions. Please simplify the query. If you believe you have received this message in error, contact Customer Support Services for more information.

Error 8632:

Internal error: An expression services limit has been reached. Please look for potentially complex expressions in your query, and try to simplify them.

Оператор IN не самый лучший да

Данные ошибки возникают не только и не столько из-за оператора IN. Если в запросе 2-3 значения, то IN-нормальное решение.

  1. Я бы не был столь категоричен. Порой нужны запросы между БД, и MERGE INTO. Да и параллелизм при вставке может перекрыть все выгоды от in memory OLTP. Бывают нужны geography и geometry типы. В общем, пока имеется масса ограничений для in memory OLTP, я бы рекомендовал пользоваться им с осторожностью.

Так да, с осторожностью и где уместно.

Некоторые рекомендации, описанные в статье я использую, например не применяю курсоры, то есть применяю, но в виде агрегата min to min. Так как у меня не web приложения, то в основном в моих разработках использую хранимые процедуры, в которых делаю все обработки бизнес логики. Не использую временные таблицы, триггеры dml. Для хранения версий хранимых процедур и истории всего кода dml использую триггеры БД и таблицу а отдельной БД для хранения всей истории изменений северного кода. А статья полезная. Мои системы трудно назвать высоконагруженными, но в любом случае нужно по возможности придерживаться рекомендаций, связанных с быстродействием. Кстати, про быстроднйствие- пробовал использовать CTE в запросе вместо подзапросов, оказалось что с СТЕ запрос медленнее в 2 раза. То есть CTE тоже надо использовать с осторожностью, исходя из необходимости и требований к быстродействию.

Круто! Для истории изменения данных тоже по возможности лучше делить БД, т е получается что-то вроде секционирования всей БД-разделение оперативных и исторических данных. Рад что публикация оказалась Вам полезной. Про CTE-в общем, рекурсивные CTE могут дать сильную просадку в производительности, т е лучше делать через временные таблицы. Сам же CTE (без рекурсии) эффективен только при небольшом количестве обрабатываемых данных. Но как отдельный пункт рекомендации еще не созрел в данном материале.

Я вообще стараюсь отделить данные от логики, то есть все таблицы хранятся в одной бд а хп в другой. Доступ к таблицам через синонимы. Это даёт возможность создать не только рабочую, но и тестовую БД. При разработке хп идентичны по коду xп, но работают с разными таблицами. В клиентском приложении просто выбираешь нужную базу тестирования и тестируешь изменения в хп. Это позволяет не создавать лишнюю тестовую БД, и к тому же использовать общие справочники для рабочей и тестовой БД. По такому принципу у меня построена система разработки карт протокола Modbus новых прошивок приборов. В тестовой БД новая карта тестируется и потом переносится в рабочую БД. Может возвращаться назад, дорабатывать и опять заменять я в рабочей БД или записываться как новая. В тестовую БД добавлены процедуры корректировки карт, в рабочей их нет. Доступ разграничения между пользователями разработчиками карт и пользователями настройками приборов. Естественно есть логи и мониторинг коннектов, который показывает в онлайн кто и что делает с БД.

Как ведёте резервные копии, восстановление и версионирование данных?

Да, веду. Все версии Хранимых процедур через триггер БД пишутся в таблицу отдельной БД. Всё доступно по поиску, по контексту.. есть просмотр. При компиляции процедуры в начало её всегда пишу описание версии. Остальное, дата, время, логины и тп берётся из eventdata() триггером БД. Откат процедуры вручную, через поиск, копирование и вставку. Все БД том числе и маster автоматически бэкапируются в отдельное место на другой сервер. Раз в день. Логи всех приложений пишутся в отдельные бд. Самый большой лог занимает за год около 4 гб. В общем он раз в год чистится, потому что в основном используется под оперативный мониторинг.

Спасибо! Было бы интересно почитать детали-предлагаю оформить в отдельную публикацию. Как думаете? Сделаете? (если конечно не является коммерческой тайной)

В общем все идеи с простора интернета, но доработанные под свои задачи. Пока времени нет писать статью, надо проект внедрять на 60 пользователей, потом может напишу небольшую статью, кому нибудь может будет полезно, особенно тем кто разрабатывает под mssqs.

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

Ну давайте по существу:

1. Вы не указали о каком типе функции идёт речь, будем считать, что это TVIF
В общем и целом это называется проблемой невозможности выполнить push-down предиката, (например при использовании в функции оконок), и в таком случае да - безусловно нужно вносить параметр явно и смотреть очень пристально на то, как оно компилируется.
НО в общем случае неприятности это может вам принести только в случае если вы используете функцию в качестве ограничивающего предиката с доп. условием в WHERE

2. Только ради этого не стоит заводит MOFG, к тому же: если вы создаетё HASH индекс, то зачем вам ещё и B-TREE? И почему HASH индекс не уникальный, если B-TREE уникальный?
В общем и целом могу порекомендовать следующее: если основной шаблон использования ID в типе - singleton lookup и вы знаете предполагаемый объем данных в этом конкретном TVP - создавайте HASH, иначе просто B-Tree и лишь в очень (ОЧЕНЬ) редких случаях нужны оба индекса.

3. Я перефразирую: нельзя использовать VIEW в качестве таблиц при написания запросов: оптимизатор гарантированно не будет счастлив, если вы сделаете соединение VIEW, которая ссылается на другое VIEW, которое содержит в определении APPLY на функцию и т.д. Т.е. суть кроется в следующем: VIEW это не таблица, при написании запросов к ней НУЖНО это учитывать.

4. Не понимаю при чём здесь "рекомендуется", речь идёт о SARGability, и в таком случае простой ссылки будет достаточно. п. 5 - то же самое

6. Нет ничего плохого в OR, просто надо знать меру (как и с IN btw), оценивайте приводит ли использование OR к излишним чтениям или проблемам с компиляцией запроса, если всё в порядке - оставляйте и даже не забивайте себе голову. Мы занимаемся разработкой, а не следованием мантрам в стиле "туда не ходи"

7. Это не совсем (и не всегда) верно, поскольку может ухудшать план исполнения, поскольку после вынесения в TVV этих значений план будет скомпилирован скорее всего как multiple seek of unknown value, это не столь критично при поиске уникальных значений, но может иметь сильнейший отридцательный эффект при поиске чего либо с cardinality > 1 строки.

9. За вас это делает оптимизатор (занимается оценкой), похоже на очередную мантру.

12. Если в ваших запросах DISTINCT SORT получается всегда дороже чем STREAM AGGREGATE, то значит оптимизатор ошибается в cardinality и вам нужно либо посмотреть что со статистикой, либо упростить запрос. (вообще к DISTINCT отношусь как жёлтому флагу, но кажется теперь начну так же относиться и к GROUP BY вместо DISTINCT).

13. Если изменить формулировку на "При проектировании таблицы в OLTP БД с сильной нагрузкой на вставку...", то это одно и допустимых решений, в остальном не очень, и да ссылки как всегда достаточно.

14. В качестве оптимизации или при проектировании seek-heavy таблицы - да, как исходное решение - нет. (у вас часто пользователи ищут строки по 50+ символов?)

17. Нет, оптимизатору в общем случае виднее, если есть проблемы - да, пробовать хинтовать, но НИКОГДА не делать этого "просто потому что принято", то же самое относится и к хинту NOLOCK.

18. Это не верно для NC модулей, поскольку может приводить к падению производительности.

23. Это просто разные функции и у каждой из них есть своя область применения:
COALESCE в T-SQL так вообще сахарок, она раскрывается:

SELECT COALESCE(a, b) FROM tbl;

SELECT
CASE
WHEN a IS NOT NULL THEN a
WHEN b IS NOT NULL THEN b
END
FROM
tbl;


соответственно вы не будете вычислять b, если у вас есть a (в случае если a и b подзапросы), НО вы вычислите a дважды (!!! это важно), один раз для выполнения assert, второй для непосредственно получения значения (таков уж T-SQL),

Проверьте то же самое для ISNULL() - все выражения внутри будут вычислены (но только и ВСЕГДА один раз)

25. И зачем вам это в таблице log'ов например?

26. Должно звучать как указывать длину при работе с любыми var* типами: [n]varchar(), varbinary(), дополню от себя: не каждая строка это "по-умолчанию" [n]varchar(255) (подставьте сюда своё любимое число).

29. А если я точно знаю, что выполнение будет только одно и мне не нужно кэшировать план?

30. Мантра, безусловно утюгом гвозди забивать неудобно, но разве плох для этого молоток? Другой разговор про цепочки из UNION (из-за возможных сложностей у оптимизатора при оценке требуемого memory grant'а), но опять же - нельзя что-то делать или не делать только потому что "так принято".

31. Краткая выжимка: Keep transactions as small and as short as possible. Ничего более тут не требуется разъяснять (это относится и к другим похожим пунктам)

32. Если речь об applock'ах, то это ооочень специфический инструмент и не стоит добавлять его как "generic use pattern", их как правило используют только в том случае, если не удаётся обеспечить достаточную изоляцию используя стандартные механизмы блокировки MS SQL Server, или если их использование слишком затратно для системы. (например сильно нагружает pool блокировок, или вываливается за thershold'ы и приводит к эскалации)

35. ... и на 100-й строчке кода искать определение TVV в начале модуля

36. Временные таблицы и TVV это отдельная и очень большая тема, в общем случае стоит всегда задавать себе вопрос: хорошо ли выпонимаете разницу в них, и почему именно в этом конкретном случае вам нужна именно временная таблица, а не TVV (помним про deferred compilation) в версиях 150+

38. Нельзя смешивать DML и DDL код в одном модуле, поскольку это приводит к фантомным перекомпиляциям (не столь актуально для 150+, но всё-же), это в принципе допустимо в скриптах, но никогда в модулях, создаетё времянки - делайте полное её определение, для индексов (почти всех типов) сейчас допускается inline определение прямо в конструкции
CREATE TABLE / DECLARE @tvar AS TABLE

39. А ещё лучше - прочтите статью о том, что такое эскалация блокировок

41. Если вам необходимо обеспечить уникальность - поднимите ограничения UNIQUE/PK, а не изобретайте велосипед (кроме того при patter'не UPSERT через MERGE указывать SERIALIAZABLE это строго говоря правило, от которого лишь в некоторых случаях можно отказаться (например OLTP бд))

44-45 - мантры, у TRY_CAST есть всего 2 адекватеных применения: проверка возможности приведения к XML и работа с sql_variant типами (у вас они есть?), select into в скриптах более чем допустим, в модулях нет - неявное создание временнной таблицы.

46. От использования SET ROWCOUNT стоит вообще отказываться, не только в DML. Были кстати кажется где-то тикеты про "а давайте просто объявим его как deprecated", но пока всё ограничилось следующей плашкой:

Important

Using SET ROWCOUNT will not affect DELETE, INSERT, and UPDATE statements in a future release of SQL Server. Avoid using SET ROWCOUNT with DELETE, INSERT, and UPDATE statements in new development work, and plan to modify applications that currently use it. For a similar behavior, use the TOP syntax.
...
Setting the SET ROWCOUNT option causes most Transact-SQL statements to stop processing when they have been affected by the specified number of rows. This includes triggers. The ROWCOUNT option does not affect dynamic cursors, but it does limit the rowset of keyset and insensitive cursors. This option should be used with caution.

т.е. на лицо "скрытый контекст исполнения", почему отвалился триггер? - кто-то в scope'е выше поставил SET ROWCOUNT

50. Не запрещено, скорее "не нужно", любителям рассказов про "немедленное освобождение места в tempdb обратно", а вы часто создаёте террабайтные таблицы в tempdb? Если да, то зачем, для этого есть обычные БД? А вообще место для "маленьких" (несколько extent'ов, я не помню точно и не смог найти источник) таблиц высвобождается мгновенно при выходе за scope, для больших - фоновым процессом за 10-20 секунд (слишком от многого зависит)
Ручная очистка таких таблиц противоречит следующей парадигме: Keep your transactions as small and as short as possible.

Круто! Спасибо за развернутую критику с детализацией и фактами. Большинство изложенного обсуждалось и не один раз и не один месяц прежде чем было формализовано в виде пунктов рекомендаций для этой публикации. Т е рассматривались все плюсы и минусы и выбраны оптимальные рекомендации для большинства встречающихся задач.

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

А бывает вложенность из пяти вьюх с со сложными ,joins, group by и подзапросами

Лучше вместо вьюх встраиваемые табличные функции или напрямую подзапрос написать

Это ещё почему? В случае простого вью это вью выступает не более чем синтаксическим сахаром и никак не влияет на оптимайзер

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

Тем не менее категоричной эта рекомендация быть никак не может

Если так посудить, то вообще все правила условны и всегда есть кейсы, чтобы их нарушить. Потому полностью согласиться не могу. Рекомендации отрабатывались годами и менялись, и были формализованы такие какие описаны в статье не за месяц и даже не за один год. В разных проектах/командах/компаниях.

Кем формализованы? SQL полицией? Случаи разные бывают

В этой публикации мной. Есть другие источники и другие мнения. Как Вы сами и написали-случаи бывают разные. У всех свой опыт.

  1. И зачем вам это в таблице log'ов например?

Вы логи не чистите что ли? А как вы ищете в логах без индекса хотя бы по дате?

А потом появляются статьи вида https://habr.com/en/articles/509322/

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

В правильном (ну совсем правильном случае) логи хранят в секционированных таблицах с clustered columnstore индексами (если данным позволяют)

Добавлю, что часто логи хранятся вообще в другой нереляционной СУБД, рассчитанной на огромные вставки данных типа сциллы. А если данные нужны оперативно и часто, то это уже не логи.

Предпочитаю логи хранить в реляционной СУБД ClickHouse.

Не вижу этого по ссылке.

Зато тут: "ClickHouse uses the relational database model."

Тут тоже: "Clickhouse is a column-oriented relational database"

Благодаря поддержке SQL (декларативный язык программирования, применяемый для создания, модификации и управления данными в реляционной базе данных) - это реляционная БД. ClickHouse поддерживает не только реляционные структуры данные, но тоже самое можно сказать и про PostgreSQL.

Мне казалось, что ClickHouse столбчатая СУБД, потому в нёё быстро все грузится и она шустрая для аналитики. Но чтобы она была реляционной... Скорее всего она поддерживает реляционную модель, но сама является не реляционной изначально. Слон-реляционная СУБД как и MS SQL, с поддержкой нереляционных возможностей.

А почему Вы решили, что columnstore OLAP DBMS не может быть реляционной? Это независимые понятия. Можете найдете ссылку на компетентный источник информации, где утверждается обратное?

Чем Вам не понравился официальный источник, который был дан выше?
https://clickhouse.com/docs/ru
"ClickHouse — столбцовая система управления базами данных (СУБД) для онлайн-обработки аналитических запросов (OLAP) " и там всё расписано как хранится. Да, он поддерживает возможности и реляционной модели, но хранит всё именно по другому не как это делают реляционные СУБД.

Там нет ни слова о том, что ClickHouse не реляционная БД. Зато указана поддержка реляционной модели данных и описаны реляционные операторы, ей поддерживаемые.

не как это делают реляционные СУБД

Вы пропустили слишком много. "Не так, как это делают традиционные реляционные СУБД со строковым хранением данных". И тут да, я соглашусь, что ClickHouse совсем не традиционная СУБД и тем более не со строковым хранением данных.

Постараюсь раскрыть что там написано: данные хранятся по умолчанию не строками, а столбцами. Вот, подсветил. В реляционных СУБД по умолчанию хранение происходит строками, но также есть поддержка столбчатого хранения через специальные индексы. Но от этого реляционные СУБД не становятся не реляционными, а просто поддерживают нереляционные модели данных. Надеюсь объяснил.

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

Но от этого реляционные СУБД не становятся не реляционными, а просто поддерживают нереляционные модели данных.

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

Давайте все же не растекаться мыслею по древу. Я предоставил две ссылки, где однозначно сказано, что ClickHouse является реляционной СУБД. Могу еще добавить: "ClickHouse – колоночная реляционная СУБД". Предоставьте Ваши ссылки, где эти утверждения опровергаются.

Все равно, что утверждать раз в MongoDB есть поддержка SQL-запросов, то она тоже может быть реляционной. На этом остановимся.

Колоночная реляционная...ужас: так можно и до документоориентированной реляционной модели дойти. Да нет такого в природе физически: либо колоночная, либо реляционная, либо документоориентированная, либо иерархическая и т д и т п

Ссылку дайте все же. Или мне еще четвертую надо привести для этого? "реляционные базы бывают с хранением данных по строкам (PostgreSQL) и по столбцам/колонкам (ClickHouse, Vertica)"

Ссылки были и от меня, и от Вас, где написано прямо что за модель данных.

Вертика - реляционная СУБД с поддержкой колоночного хранения.

Я не видел от Вас ссылки, где утверждалось, что ClickHouse не реляционная СУБД. Были лишь Ваши домыслы, что OLAP или ColumnStore СУБД не может быть реляционной. Дайте ссылку, как я, процитировав утверждение, что ClickHouse не реляционная СУБД.

Поправка: Vertica как и ClickHouse - это колоночно-ориентированная аналитическая СУБД

Есть Wide Column Stores, а есть реляционные.

Вот и дайте ссылку, где доказывается, что эти два понятия не совместимы и не может быть Wide Column Stores реляционной СУБД. Зачем так много спорить и писать, если достаточно просто дать ссылки?

https://ru.m.wikipedia.org/wiki/ClickHouse

Кстати, на счёт слона ошибался-это не реляционная СУБД, а...впрочем Вы просили ссылку: https://ru.m.wikipedia.org/wiki/PostgreSQL

И для сравнения: https://ru.m.wikipedia.org/wiki/Microsoft_SQL_Server

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

https://ru.m.wikipedia.org/wiki/ClickHouse

Может я плохо читал, но в упор не вижу, где тут написано, что ClickHouse не реляционная СУБД. Можете процитировать эту фразу?

Надеюсь теперь Вы поняли в чем разница именно типов СУБД

Не понял. СУБД может быть одновременно множества типов. И только некоторые из них считаются взаимоисключающими, как OLAP и OLTP.

Все 3 ссылки прочтите пожалуйста. Первые предложения и найдете разницу. СУБД может быть только одного типа, куда его конкретно относят, но также бывают надстройки для поддержки и других моделей данных. Но! Сама СУБД относится только к одной модели, а не к нескольким. Забудьте про маркетинговый ход о многомодельной модели данных. Такое физически не создать без скрещивания ужа с ежом. У Вас будет физически одна модель в зависимости какую СУБД Вы выберите+эта же СУБД будет иметь некие надстройки, которые позволяют поддерживать и другие модели. Например, в MS SQL для этого есть колоночные и пространственные индексы.

Да прочитал я. Говорю же не вижу в упор, где написано, что ClickHouse не реляционная СУБД. Процитируйте и скрин сюда поместите с этой фразой.

Мы же не Ваши субъективные ассоциации обсуждаем, а просто факт, который должен быть явно зафиксирован. Я Вам четыре ссылки дал где открытым текстом написано что ClickHouse реляционная СУБД. Вот и от Вас жду ссылки с аналогичным текстом не допускающим двоякого толкования.

СУБД может быть только одного типа

Это лишь Ваше личное мнение, с которым я не согласен.

Читаете и не видите в упор: "ClickHouse — это колоночная аналитическая СУБД" и "Microsoft SQL Server — система управления реляционными базами данных (РСУБД)" и "PostgreSQL (произносится «Пост-Грес-Кью-Эл»[7]) — свободная объектно-реляционная система управления базами данных (СУБД)".

Если и сейчас не видите разницу, то закончим на этом, т к я не знаю как ещё объяснить, что Земля круглая.

Ну и где написано что ClikHouse не реляционная? Это колоночная реляционная аналитическая БД. И то, что где-то слово "реляционная" пропускают совершенно не доказывает, что она не реляционная.

Вы хотите чтобы я повторял Ваши ассоциативные заключения. А я не хочу.

Понятно. Остановимся на этом.

Термин "Реляционная" относится к логической модели данных.
То есть, для пользователя данные представляются в виде кортежей с одинаковым набором полей в каждом. Когда в ClickHouse описывается таблица

CREATE TABLE example
(
    dt Date,
    ts DateTime,
    value Float32 CODEC(Delta, ZSTD)
)
ENGINE = MEMORY

это автоматически переводит модель в класс реляционных. Как оно хранится под капотом - это вне классификации логических моделей.

Другой аргумент: если в CH - не реляционная модель, то какая? Выбор-то небольшой:

Иерархическая модель
Сетевая модель
Реляционная модель
Модель «сущность — связь» (ER)
Модель «сущность — атрибут — значение»[en] (EAV)
Объектно-ориентированная модель (из ООП)
Документная модель
Звёздная модель и модель снежинки

Кроме "реляционной", к CH ничего больше не подходит.

Обратимся к словарю.

Реляционная система управления базами данных (РСУБД) — СУБД, управляющая реляционными базами данных.

Реляционная база данных — база данных, основанная на реляционной модели данных.

То есть, по определению, СУБД, поддерживающая реляционную модель данных, является РСУБД. Если есть другие определения - давайте, рассмотрим их.

Нет, классифицируют не так СУБД. В данном случае ClickHouse и Vertica - это аналитические СУБД, поддерживающие в том числе реляционную модель, но сами СУБД колоночные (столбчатые) аналитические.

Нет, классифицируют не так СУБД

Поэтому я и попросил дать ваше определение, если вас не устраивает общепринятое, которое я привёл выше. Итак, РСУБД - это ...

поддерживающие в том числе реляционную модель

А какие ещё логические модели (кроме реляционной) поддерживает CH?
Выше перечислен их список. Кроме реляционной, ничего не подходит. Одна запись в CH - это кортеж.

Если схема
example (dt Date, ts DateTime, value Float32)
То нельзя вставить dt без value. Запись - неделимый кортеж, как и требует реляционная модель.

Следуя этим ссылкам википедии, я пришёл к определениям на страницах википедии, которые выписал. А других определений там нет. Поэтому у вас и спрашивают цитаты.

Первые предложения из страниц, которые я тоже выше указал.

Первые предложения из страниц, которые я тоже выше указал.

Хорошо. Попробуем.
Первая ссылка https://ru.m.wikipedia.org/wiki/Реляционная_СУБД

Реляционная система управления базами данных (РСУБД) — СУБД, управляющая реляционными базами данных

Вроде это ровно то, что я цитировал, и с чем вы не согласны. Или нет?

Вторая ссылка https://ru.m.wikipedia.org/wiki/PostgreSQL

PostgreSQL (произносится «Пост-Грес-Кью-Эл»[7]) — свободная объектно-реляционная система управления базами данных (СУБД).

При CH тут ничего нет.

Третья ссылка

ClickHouse — это колоночная аналитическая СУБД с открытым кодом, позволяющая выполнять аналитические запросы в режиме реального времени на структурированных больших данных. Изначально разрабатывалась компанией Яндекс[4][5][6], но впоследствии разработка полностью перешла в отдельную компанию ClickHouse Inc[7].

Из чего вы сделали заключение, что "она поддерживает реляционную модель, но сама не является реляционной СУБД". Вот этот переход я не понимаю.

но сами СУБД колоночные (столбчатые) аналитические

Колоночная - способ хранения.

Аналитическая - предназначение.

Логической модели данных это перпендикулярно.

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

Типов СУБД очень много

Вот они все:
https://ru.wikipedia.org/wiki/Система_управления_базами_данных

Что вы здесь подразумеваете под "типом СУБД", если не классификацию по модели данных? По степени распределённости? По способу доступа?

РСУБД - это классификация по модели данных

Весь этот холивар возник, т к утверждалось, что логирование идёт быстро в реляционную СУБД. Я же уточнил, что СУБД не реляционная, а колоночная.

Я же уточнил, что СУБД не реляционная, а колоночная

А вас поправили, что она и реляционная, и колоночная.

Ещё раз читаем что в Вики написано. Устал спорить. Предлагаю закончить. В конце концов тема публикации не об этом. И какова цель спора,и если все равно каждый останется при своем мнении? Потому хватит.

Моя цель уточнить мои знания. Мне говорят: чёрное - это белое. Я спрашиваю: как так? Да вот же, на википедии написано. Спрашиваю: где написано? - Вот ссылка, читайте! А я по ссылке не вижу. Вот и думаю, то ли я дурак, то ли что?

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

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

Мы читаем с Вами одно и тоже и делаем разные выводы. Однако, к теме материала оно не имеет отношения. Потому и нет смысла дальше спорить.

  1. Отличная ссылка. Спасибо!

  1. Я понимаю зачем автор статьи использует этот хинт, но в Enterprise версии сервера он не нужен. Во всех остальных да, его необходимо указывать, что бы Сиквел использовал вьюшку, зря что ли мы ее создавали? :)

  1. На самом деле димамический SQL сильно помогает бороться с пунктом 6 (Оператоты OR and IN) и резко сокращает сложность запроса и время его выполнения.
    Да писать его сложно, сопровождать еще сложнее, но порой без него (особенно в различных веб приложениях с множественными фильтрами) жизнь немыслима :)

  1. Работаю часто в Enterprise версии сервера и лучше его указать. Это не nolock.

  1. в таком случае запрос лучше строить на стороне сервиса, а не на стороне СУБД или если вариантов немного, то сделать ветвление кода: либо через IF-ELSE, а еще лучше вызывать нужные хранимки, чтобы не раздувать саму хранимку.

в таком случае запрос лучше строить на стороне сервиса, а не на стороне СУБД

Это легко делается на стороне СУБД с использованием нескольких сервисных функций и препроцессора при деплое. Подробно описывать - это уже на статью потянет. Может как-то соберусь и напишу. Клиенты, увы, бывают уж слишком тупы, чтобы на них динамически запросы формировать (камень в сторону SSRS и CrystalReports).

Соглашусь, прошу скинуть ссылку как напишите

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

Все фильтрации применять сразу в запросе, т е не рекомендуется сначала вызвать функцию, а потом применять фильтр

Зависит от функции. Например:

CREATE TABLE dbo.tmp_tmp (
  ID int identity(1,1) PRIMARY KEY CLUSTERED,
  IsActive bit NOT NULL
)
INSERT INTO dbo.tmp_tmp (IsActive) VALUES
  (1), (0), (0), (1), (0), (0), (1)
CREATE INDEX IsActive_Idx ON dbo.tmp_tmp(IsActive)

Создаем функцию:

CREATE FUNCTION dbo.fn_func_table()
RETURNS TABLE AS RETURN (
  SELECT ID, IsActive FROM dbo.tmp_tmp )

Проверяем:

SELECT t.ID FROM dbo.fn_func_table() AS t WHERE (t.IsActive = 1)

  |--Index Seek(OBJECT:([test].[dbo].[tmp_tmp].[IsActive_Idx]), SEEK:([test].[dbo].[tmp_tmp].[IsActive]=(1)) ORDERED FORWARD)
Table 'tmp_tmp'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Для сравнения:

DROP FUNCTION IF EXISTS dbo.fn_func_table
GO
CREATE FUNCTION dbo.fn_func_table (@IsActive bit)
RETURNS TABLE AS RETURN (
  SELECT ID, IsActive
  FROM dbo.tmp_tmp
  WHERE IsActive=@IsActive )
GO
SELECT t.ID FROM dbo.fn_func_table(1) t

  |--Index Seek(OBJECT:([test].[dbo].[tmp_tmp].[IsActive_Idx]), SEEK:([test].[dbo].[tmp_tmp].[IsActive]=(1)) ORDERED FORWARD)
Table 'tmp_tmp'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Иными словами, для inline функций никакой разницы нет.

Разница возникнет, как только функция перестанет быть inline (в ней появится блок BEGIN ... END).

Верно, лучше использовать встраиваемые функции и ещё лучше если возможно фильтрацию делать в ней, а не выносить после вызова. Но это если можно по смыслу, не размазывая логику.

Тут был простой случай. Но ведь на практике фильтрации требуется делать далеко не по одному полю и совсем не обязательно на равенство. Параметризация тут может привести к совершенно неудобной в использовании функции.

Здесь имелось в виду, если можно сделать унификацию и фильтрацию по таблицам, которые есть в функции, чтобы не размазывать логику.

Ну это вопрос не столько к кодированию на SQL, сколько к проблемной части. В общем случае, для inline функции производительность фильтрации в ней и вне её одинакова, что я показал выше. Поэтому смысл фильтровать в inline функции возникает только исходя из требований бизнес-логики.

Не стоит в общем случае полагаться на оптимизатор. Лучше писать так, чтобы 100% работало без всяких но в надежде на встраиваемую функцию. Сегодня встроит, завтра поменяют чего и не встроит и т д и т п.

А какое отношение это имеет к inline функциям? Они потому и inline, что оптимизатор сначала встраивает их в запрос, а только после этого строит его план. Поэтому для него нет никакой разницы, указана фильтрация в теле inline функции или вне её.

Нет, конечно, если Вы сможете привести пример, когда такая разница возникнет - тогда другое дело. Приведете?

Рекомендуется в условиях фильтрации и соединении слева использовать только индексированные поля.

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

А вот использовать в в условиях фильтрации и соединении слева выражение, полностью совпадающие с выражением в WHERE частичного индекса - очень хорошо.

Так же, вместо шести индексов (a,b,c,d,e), (a,b,e,c,d), (a,b,d,e,c), (a,b,d,c,e), (a,b,c,e,d), (a,b,e,d,c) часто эффективней один (a,b) INCLUDE (c,d,e), или, иногда, (a,b,c) INCLUDE (d,e)

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

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

Могу ближе к проблемной части. Пусть у нас есть таблица, в которой записи по каким-то причинам не удаляются, а лишь помечаются удаленными, установкой в 1 поля IsDeleted bit DEFAULT 0.

В этом случае индекс (a,b) WHERE IsDeleted=0 будет эффективней, чем индекс (IsDeleted,a,b). Причем существенно, так как статистики для первого индекса будут заметно адекватней, чем для второго.

Огромное количество индексов не равно деградация системы

Я этого не писал. Перечитайте: "деградации производительности на операциях модификации таблицы"

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

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

По моему очевидно, что по индексируемому полю искать быстрее, чем не по индексируемому, если конечно таблица не меньше 10 000 строк (или такая, которая не может быстро вся быть загружена в оперативную память).

Я уже не знаю, как выделить слово ТОЛЬКО

Претензия была не к использованию индексированных полей, а к использованию только индексированных полей.

Вы же сами написали:

Рекомендуется в условиях фильтрации и соединении слева использовать только индексированные поля.

А я уже третий раз пишу, что часто лучше, чтобы из 4-5 полей в условиях фильтрации одной таблицы, только 2-3 были индексированы, а остальные либо были включены в INCLUDE список, либо фильтровались в WHERE частичного индекса.

Более того, если из этих 4-5 полей в условиях фильтрации одной таблицы 1-2 уже составляют её уникальный кластерный индекс, то остальные три поля вообще не зачем в этот индекс включать и пусть они остаются не индексированными.

Вот люблю я "magic numbers", откуда число 10000?

Не всегда index-seek быстрее scan'а: сильно ли быстрее будет seek, если плотность созданного вами индекса = 1/3 (3 уникальных занчения в колонке) при равномерном распределении значений по таблице и объеме ну, скажем 1M+ строк?

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

Вы не туда ушли, но правы.

Если вообще вытаскивать почти все данные из таблицы, то проще уже просканировать всю таблицу. Но мой ответ был дан по другому вопросу, а Вы завернули не туда. Естественно индексы нужно использовать с умом, а именно когда seek будет быстрее скан. Обычно так и происходит при правильном индексирования и если не выгребать большую часть данных из этого индекса/таблицы.

Вы здесь говорите о фильтрованном индексе (a, b) с предикатом фильтра IsDeleted = 0?
Индекс, начинающийся с IsDeleted у которого плотность = 0.5 это просто нонсенс, особенно учитывая, что в гистрограмме статистики будет только совершенно ненужный мусор. (leftmost column). При подобном "изобретении" нужно накладывать запрет на профессиию.

IsDeleted у которого плотность = 0.5

Не знаю что при чем тут плотность индекса и как Вы её посчитали не зная fillfactor или иные настройки его разреженности. А селективность и кардинальность тут может быть любая. Например, если в таблице из миллиона строк 990 тыс. помечены, как удаленные, то кардинальность выборки по IsDeleted=0 10000, а IsDeleted=1 990000. При этом по отдельности кардинальности a и b могут вполне быть 100000.

И если Вы действительно предлагаете тут индекс (a,b,IsDeleted), зная, что 99% выборок идут с условием IsDeleted=0, то соглашусь, что

При подобном "изобретении" нужно накладывать запрет на профессиию.

)))

В таком случае вообще лучше таблицу разделить на две-те, где много данных и те, где мало. Или ввести секционирование с двумя секциями.

Миллион записей - это все же очень мало. А если секционировать по IsDeleted, то при установке его в 1 это будет не только обновление индекса, но еще и физическое перемещение записи из одной секции в другую. Такие вещи лучше все же делать не на лету, а периодическим заданием по отдельному критерию.

На самом деле это был очень упрощенный пример. На практике чаще все сложнее. Например, таблица вида:

CREATE TABLE ttt (
  ID bigint INDENTITY(1,1),
  SomeLot int NOT NULL,
  SomeItem int NOT NULL,
  Analytic1 int NULL,
  ...
  AnalyticN int NULL,
  ValidFrom datetime2 NOT NULL,
  ValidUntil datetime2 NULL,
  CONSTRAINT ttt_PK_Idx
    PRIMARY KEY CLUSTERED (SomeLot, SomeItem, ValidFrom)
)
CREATE UNIQUE INDEX Valid_Idx ON ttt (SomeLot, SomeItem)
  WHERE ValidUntil IS NULL

Когда вставляется запись с уже существующим сочетанием (SomeLot, SomeItem), то уже существующей записи с этим сочетанием и ValidUntil IS NULL присваивается значение из ValidFrom вставляемой записи. Вместо удаления записи, устанавливается только ValidUntil в текущее время.

С одной стороны, это позволяет по первичному ключу получить историю сочетаний (SomeLot, SomeItem) на любую дату. С другой стороны, текущие значения вынимаются моментально по частичному индексу. Ну и обновление кластерного индекса тогда идет только добавлением в него записей, что заметно снижает издержки на его модификацию и их последствия.

Если же записи по одному сочетанию (SomeLot, SomeItem) могут приходить чаще, чем раз в 100 наносекунд, то приходится уже вместо datetime2 использовать bigint с абстрактным временем.

На практике логическое удаление так делают: сначала метят, затем физически удаляют/переносят как например в 1С.

Но есть и другой пример, активные записи. Это не те, что удалены или не удалены. А те, с которыми работают. Например, открытая сделка/проводка и т д. Таких записей обычно меньше 1 млн, порой даже меньше 100 000. Потому часто видел реализацию и сам так делаю, что такие записи хранят отдельно или в отдельной секции для быстрого доступа. Аналог реализации постоянного кэша данных. Затем когда закрывают сделку/проводку/документ, сразу же запись перемещают в основную таблицу, где много данных. Если там очень много данных, то там тоже свои секции. Очень удобно.

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

запись перемещают

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

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

такие записи хранят отдельно или в отдельной секции для быстрого доступа

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

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

Делают, и в NAV, и в CRM, и в 1С и во всех взрослых системах, которые я видел... В том числе в системах реального времени для слежения движения судов и самолётов.

Темпоральные таблицы, нет?

Зачем хранить в одном месте и актуальные данные, и исторические? А как чистить то, что вам более не нужно?

Темпоральные таблицы, нет?

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

Зачем хранить в одном месте и актуальные данные, и истрические?

Например затем, что исторические данные тоже нужны, хоть и реже, чем актуальные.

А как чистить то, что вам более не нужно?

Секционируя по ValidFrom. Но при этом, если из последней секции запись с ValidUntil IS NULL должна быть перемещена в новую архивную секцию, то она предварительно дублируется и закрывается фиктивной записью с более актуальным ValidFrom. Если сам оригинальный ValidFrom все же важен, что изредка случается, то для него выделяется отдельное поле.

Больше похоже на DWH, чем на OLTP под нагрузкой.

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

на время A (до секунду) баланс счёта - 100
И прилетает вам событие, которое по каким-л. причинам вы обрабатываете позже о том, что в момент А-1 со счёта было снято 50
И бежите вы доблестно задним числом править аудированные данные
Ну а потом, как водится, приходит аудиторская проверка.

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

Чего вы достигаете:
1. Ваши запросы про баланс счёта на момент A всегда вернут один и тот же результат.
2. Не существует простого способа править данные в исторической части темпоралки - вы автоматически защищены от чьих-нибудь толстых пальцев.
3. Если уж совсем упороться - делаем не обычную темпоралку, а Ledger таблицу, с контрольными суммами, порядками операций аудитом из коробки и прочими прелестями.

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

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

вы отдали аудированный отчёт по допустим балансу счёта, который ведёте в таблице вроде вашей

прилетает вам событие

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

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

делаем не обычную темпоралку, а Ledger таблицу

Это уже в РФ вряд ли кому интересно. Я не знаю ни одного клиента, планирующего переход на MS SQL 2022. Но почти все планируют переход на PostgreSQL. Это даже не считая того, что как и любая фича, это требует годы для стабилизации. Кроме того, существует масса способов добиться полного аудиторского следа, не повышая нагрузку на продуктивную СУБД криптографией.

Есть и даже крупные компании, кто перешёл с 2019 на 2022 скуль

Я не знаю ни одной. Купить официально лицензию сейчас невозможно. Поддержку - тем более. Сертификации нет и быть не может. Так что колбасит сейчас всех. И это относится далеко не только к MS SQL. Вот РЖД уже третью попытку делает с DB/2 и Oracle на PostgreSQL перейти. Все клиенты в шоке.

К тому же, по моему опыту, переходить на последнюю версию очень рискованно. Если бы не санкции, я бы сейчас, возможно, занимался переходом на 2019 с 2017 и 2016. Но уж точно не на 2022. Не помню, чтобы новая версия MS SQL ни на одной из клиентских БД не преподнесла сюрпризов. Вот когда выходит следующая версия, тогда уже можно накатывать последний CU и проверять.

Так что и Вам рекомендую больше смотреть на PostgreSQL и потихоньку забывать о приколах MS SQL )

Лицензии покупают как-то, но покупают. На счёт опасений про последнюю версию верно, но не так страшно, начиная с 2019. И конечно сначала обновляют тестовый стенд и на нем проверяют весь функционал прежде, чем обновлять прод. Главное, использовать российское облако, а ещё лучше - свое корпоративное облако.

И все, что древнее 2019 версии уже старье.

"Как-то" можно купить, чтобы все же поставить. Но официальным это "как-то" не назовешь. Поэтому и не знаю ни одного своего клиента, который покупал бы такие "серые" лицензии. Так же понятно, что 2022 не сертифицируют в ближайшем будущем. А действие сертификатов на более ранние версии, включая 2019, приостановлено. Аналогичная ситуация с Windows Server. Много ли клиентов согласятся переходить на не сертифицированную СУБД? Как минимум, персональные данные есть у всех, а штрафы платить желания мало.

И все, что древнее 2019 версии уже старье.

Подавляющее большинство клиентов соглашаются тратить деньги на переход на новые версии только под давлением поставщика, чтобы не остаться без поддержки. И я их понимаю. Работает - не трожь )

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

Если следовать санкциям, то остаётся пользоваться только валенками и тулупами. Смартфонами и телевизорами нельзя равно как и транспортом, т к запчасти как минимум зарубежные.

Дайте, пожалуйста, ссылки на законы, из которых Вы сделали такие странные выводы.

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

Сам Закон, приказ ФСТЭК, административная и уголовная ответственности. До уголовной ответственности можно доиграться только если был причинен ущерб. Но и по КоАП РФ штрафы до 18 миллионов рублей мелкими не покажутся.

Ваш ход? Жду ссылок.

Этим занимаются юристы, как не нарушив закон соблюсти интересы компании. Есть законы, а есть жизнь. Последняя более практичная, чем просто текст в законах. Вот юристы пусть этим и занимаются.

Есть законы, а есть жизнь.

Незнание закона не освобождает от ответственности.

Или Вы надеетесь на коррупцию и взятки?

Не освобождает тех, кому это светит. Разработчикам не светит, т к у них нет официально зарегистрированной зоны ответственности в этом вопросе.

И как-то проходят проверку и живут.

Вы больше пугаете, чем есть на самом деле. В конце концов у компании есть целый штат юристов.

Я не пугаю. Я разъясняю действующее законодательство. А уж нарушать его или нет - личное дело каждого.

у компании есть целый штат юристов

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

Посмотрите, например, как ФАС штрафует крупнейшие компании в РФ. Думаете у них юристы плохие? )))

Разработчикам не светит, т к у них нет официально зарегистрированной зоны ответственности в этом вопросе.

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

Мы с Вами в разных реалиях живём по ходу. Так и не понял за что могут штрафануть коммерческую компанию, у которой не был доказан факт слива данных и у которой все персональные данные хранятся на собственных серверах на территории РФ. На счёт что руководство там что-то на кого-то сольет-это в мелких и бессовестных конторах. В крупных компаниях даже у архитектора системы банально нет таких доступов, чтобы что-то вообще такое сделать. Даже у дба не все права есть.

не понял за что могут штрафануть коммерческую компанию, у которой не был доказан факт слива данных и у которой все персональные данные хранятся на собственных серверах на территории РФ

За использование при обработке и хранении персональных данных не сертифицированных ФСТЭК программно-аппаратных средств.

Я же даже ссылку на статью в cnews Вам предоставил, где все максимально разжевано для несведущих в юриспруденции.

В крупных компаниях даже у архитектора системы банально нет таких доступов, чтобы что-то вообще такое сделать. Даже у дба не все права есть.

Права то тут при чем? Для того, чтобы сотрудника сделали "стрелочником" никаких прав ему не надо. Наоборот, нужны права руководству, чтобы подчистить свои распоряжения или утверждения в информационной системе. Если такие вообще были.

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

Да и в любом случае, даже если Вас лично не сделают виноватым, то многомиллионные штрафы, выплаченные Вашим работодателем, по карману Вас по любому ударят. Пусть даже косвенно, срезанием премий, отмене ДМС или добровольно-принудительному переводу на более низкооплачиваемую должность. Или зря Вы надеетесь, что бизнес найдет способы компенсировать затраты, без урезания ФОТ.

Вы в каких-то странных фирмах работаете.

Вот за 40 лет работы ни одного исключения не встречал. Стабильно виновен оказывается "стрелочник", а не руководитель.

Говорю: у Вас странный работодатель/клиент. Не работайте с такими. А вину ещё нужно доказать особенно если в трудовые обязанности не входило то, в чем обвиняют, то в первую очередь обвиняемую сторону запросят как так получилось и где доказательства. Доказывать свою не вину Вы не обязаны по закону. Да, и встречный иск за клевету никто не отменял.

Будем считать, что Вам очень повезло. Если как-нибудь решитесь просмотреть в ГИС Правосудие, то убедитесь, что в случае каких-либо инцидентов, особенно если дело касается КОаП, а не УК РФ, руководство несет ответственность очень редко. У него больше возможностей назначить "стрелочника". А инстинкт самосохранения это требует.

По КоАП ток юрлицо или должностное лицо, представляющее это юрлицо. У меня лично нет доверенности представлять компанию, а значит по КоАП не привлечь.

Это Вы опять не читали. А мне просто лениво было копировать, что по части 8 штраф на граждан в размере от тридцати тысяч до пятидесяти тысяч рублей, а по части 9 - уже от пятидесяти тысяч до ста тысяч рублей

Если человек невиновен, доказать обратное сложнее, т к штраф стрясти выгоднее с юрлица.

Тут Вы заблуждаетесь. Более понятным примером для Вас будет, возможно, штраф ГИБДД. Обжаловать Вы его, конечно можете. Но для этого именно Вы обязаны доказать свою невиновность. Причем, если дело затягивается, от уплаты штрафа Вас никто не освободит. Это потом, в случае маловероятного успеха, Вы будете иметь право его вернуть.

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

Кста, хороший пример!

Отвечу также: если нет машины, т е если Вы не являетесь по докам владельцем машины, то с Вас стрясти штраф ГИБДД нужно ну очень постараться и куда проще этот штраф стрясти с тех, у кого эта машина есть.

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

Главное правильно оформиться и внимательно прочитать свою должностную инструкцию.

Вы действительно думаете, что если правильно оформите на себя автомобиль и внимательно изучите ПДД, то не будете получать штрафы ГИБДД? )))

Просто не нужно оформлять на себя машину.

Тогда и не оформлять трудовые отношения. По той же логике. Нет документов - нет ответственности.

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

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

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

Ну а потом доказывайте, что это не по своему решению, а по распоряжению руководства, Вы эту БД развернули на несертифицированную СУБД c несертифицированной Windows. А руководство быстро найдет сертифицированный MS SQL 2017 под Linux и будет утверждать, что Вы по своей инициативе перенесли БД с неё. Ведь заплатить 100-200 тыс. рублей (или даже 500-800 тыс.) кто-то должен и никому не хочется оказаться крайним.

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

Вы сейчас описываете каких-то не руководителей, а мудаков. Предпочитаю работать с адекватными профессионалами, чего и Вам желаю.

Одно дело профессионализм, а совсем другое - честно заплатить 800 тыс. рублей из своего собственного кармана, даже не попытавшись свалить вину на кого-то другого.

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

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

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

При чём тут оправдание? Свой предел есть у каждого. Ну за 2 миллиона потенциальной выгоды Вас не купили. А если бы наоборот? Если бы у Вас была квартира в ипотеке и Вы точно знали бы, что потеряв эти же 2 миллиона рублей потеряете и квартиру?

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

задайте этот же вопрос своему руководству

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

Опять оправдания. У меня тогда была ипотека и кредит на лечение. Ещё раз: человек должен оставаться человеком не смотря ни на какие условия. Если Вы готовы потерять свое лицо не важно по каким причинам, то это Вы и оправдания Вам не будет и будете с этим жить всю оставшуюся жизнь. Лично я не такой тем более с людьми, с которыми общаюсь и работаю.

То, кого Вы описали, это мелкие и скользкие люди, с которыми не стоит иметь никаких дел, потому что чуть что они постараются Вас подставить. Стоит ли вообще с такими людьми строить что-то серьезное?

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

Стоит ли вообще с такими людьми строить что-то серьезное?

Точно не стоит. Но как узнать это о человеке?

Главное самому оставаться человеком. Как узнать? По общению, из опыта предыдущих коммуникаций, обратных связей. В крайнем случае, если этот мудак Вас решит подставить, на этом сразу крест в дальнейшем работать с таким "чудом". Мудаки всегда оставляют после своих гадких деяний вонючий след, который отдает зловонием до конца их жизни. Они думают, что сделали правильно и оправдываются, но от них уже воняет. Может гниют изнутри. Не знаю.

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

Только если захочет стрелять себе в ногу. Крепостное право отменили.

А при чем тут крепостное право? Поставьте себя на место владельца компании. Чем покрывать убытки и откуда взять оборотные средства для операционной деятельности? Перекредитоваться, обвалив курс своих акций и обанкротиться? Ну даже если так, то потеряете работу без последних зарплат и выходного пособия, так как предприятие банкрот и взять с него нечего.

У Вас окологос и гос конторы, потому такое отношение к своим сотрудникам как к г*вну.

Я же явно перечислил свои проекты. Сейчас ЕвроХим, СУЭК, СГК, НТК, которые фактически являются частной собственностью Андрея Мельниченко. Где вы тут госконторы углядели? У Вас вообще как со здоровьем, с общим самочувствием?

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

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

Сбер - официально государственное предприятие, принадлежащее Правительству РФ. Как же Вас так занесло? )))

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

Ага. Еврохим на 22 месте, СУЭК на 24 месте среди крупнейших компаний России. Но они для Вас небольшие.

А вот Озон, вообще не попавший в рейтинг, и Лаборатория Касперского, находящаяся в нем на 339 месте, уступая по объемам реализации и Еврохим, и СУЭК более, чем в 10 раз крупные? Очень оригинально )))

Если смотреть рейтинг по прибыли по данным Forbes, то ЕвроХим на 16-ом месте, СУЭК на 19-ом, а вот такая мелочь, как Озон или Лаборатория Касперского в этот рейтинг вообще не попала.

В Сбере работал, когда он ещё был негосударственным по бумагам. Про Ваши компании-не на слуху, а значит как бренды они слабы. И что-то я сомневаюсь, что они вносят вклад в ИТ, развивая открытые решения и продавая свои наработки.

Если ты разработчик или другой спец в ИТ, то лучше работать там, где это развивают, а ещё лучше если это и является главным бизнесом компании.

В Сбере работал, когда он ещё был негосударственным по бумагам.

Не помню такого. Он никогда не приватизировался.

компании-не на слуху, а значит как бренды они слабы

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

И что-то я сомневаюсь, что они вносят вклад в ИТ, развивая открытые решения и продавая свои наработки.

Что-то я не понял. Открытые решения на то и открытые, что они доступны бесплатно, а не продаются.

Если ты разработчик или другой спец в ИТ, то лучше работать там, где это развивают, а ещё лучше если это и является главным бизнесом компании.

А с чего Вы вдруг решили, что это не так? Я почти все время работаю на стороне системных интеграторов. Было только несколько перерывов, когда меня по результатам очередного проекта переманивали на существенно большую зарплату. После чего опять возвращался к интегратору. Сейчас мне выгодно работать стопроцентно на удаленке на холдинг СУЭК, ЕвроХим, НТК и СГК, Благо интересных проектов там много как раз по оптимизационным задачам и прогнозированию. Но числюсь в штате я все равно у системного интегратора ЦТиП

Просто мне сейчас интересны IT решения для промышленности. Надоест - займусь чем то еще сложнее.

даже если так, то потеряете работу без последних зарплат и выходного пособия, так как предприятие банкрот и взять с него нечего

Не представляю, как РЖД обанкротится со штрафа 18 миллионов. Просто заплатит и продолжит всё по-старому. Если бы у них была возможность урезать з/п и сохранить качество персонала, они бы давно это сделали, не благотворительная же организация. Если кто-то примет решение привязать урезку з/п всем по больнице к штрафу, это будет чудовищно глупо и некомпетентно.

РЖД как раз легко. В головной организации там все равно только топ-менеджмент. На втором уровне около сотни филиалов и примерно столько же дочерних компаний. А числится Вы будете в выделенной местной мелкой чисто IT компании (льготы же!), которую обанкротить даже из-за пары миллионов может оказаться выгодным, так как капитальных вложений у нее нет, а создать новую и принять туда нужных людей из старой проблем не составит.

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

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

Снимите розовые очки и просто представьте себя владельцем бизнеса с оборотными средствами в несколько миллионов рублей и штрафом в 18 миллионов рублей по вине нескольких Ваших сотрудников. Чтобы Вы сделали?

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

Вот именно: максимум увольнение причем выгодно, если по собственному, чтобы потом без суда со стороны уволенного. А не спихнуть ответственность со стороны законов по персональным данным.

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

То, что Вы написали, это мышление мелкого и недалёкого предпринимателя.

в нормальных компаниях, считают, что виноваты все

Но при этом, отвечать из своего кармана должен только один - собственник? Охренительная у Вас логика )))

Отвечать буду все, но удар принимает лидер. Если собственник не готов к этому, то пусть и дальше сидит молча в своей говноконторе, не выпячивает какой он крутой и его фирма, а признается кто он есть на самом деле. Дерьмо всегда воняет как его красиво не спрячь и как красиво не оформи.

Отвечать буду все, но удар принимает лидер.

Вы хотите сказать, что весь штраф собственник должен компенсировать из кармана генерального директора? Еще веселее.

Если собственник не готов к этому

Собственник - это, например, Вы, купившие акции этой фирмы и раз в квартал или даже в год на собрании акционеров формирующие стратегию фирмы. И к чему в этом случае Вы должны быть готовы?

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

Собственники несут полностью всю ответственность за действия фирмы. Что естественно. А дальше согласно ТК РФ может поступить, но только в рамках ТК РФ, а не свалить все на одного. Так не делают. А если у Вас так делают, то читайте мой коммент выше. Это не оскорбление, это факт. Руководитель может поступить как мудак, может быть мудаком, а может быть лидером. Последних очень мало, но они есть. Те, кто аргументированно умеет сказать НЕТ выше стоящему руководству и защитить права свои и своих подчинённых. Но конечно и интересы бизнеса тоже отстаивает, но не в ущерб корпоративной культуры и этики. Это одна из важнейших функций руководителя. А сразу уволить или свалить все-это удел мудаков и очень слабых личностей. И да, чем больше имеешь, тем больше платишь и покрываешь риски. Не готов? Не владей.

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

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

а не свалить все на одного

Вы только что открытым текстом предложили собственникам свалить все на одного лидера - генерального директора.

Но Вы так и не ответили на мои вопросы:

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

Вот сначала ответьте, потом можно будет продолжать.

Я не управленец, но как-то крутые лидеры делают так, что не увольняют и не сваливают. И предлагаю закрыть тему: мне неинтересна она вообще. Меня интересует отношение и если оно хорошее и доверительное, то сработаемся, иначе-нет.

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

У исполнителей нет никаких отношений с собственниками, только с руководством компании и то не напрямую. Первый удар всегда получает руководство, на то оно и руководство. Исполнители и получают в разы меньше в том числе потому что зона ответственности небольшая. Это как в семье: есть родители, а есть дети. За косяки детей отвечают родители. Здесь также. Родителю важно научиться взаимодействовать с ребенком и воспитывать его, а не тупо наказывать. Надеюсь сейчас донес Вам простую и практичную идею по взаимодействию.

в разы меньше в том числе потому что зона ответственности небольшая

Естественно, компенсировать последствия должны пропорционально. Например, пропорционально заработной плате (дивидентам для собственника). Если собственник вложит пять миллионов, директор два миллиона и руководитель виновного подразделения миллион, то остальные 11 миллионов распределятся между сотней других работников. По 100 тыс. в среднем.

За косяки детей отвечают родители.

Сотрудники что ли несовершеннолетние? Или Вы ратуете за то, чтобы права у сотрудников были, как у несовершеннолетних, а права их руководителей - приравнивались к родительским? Боюсь, на практике это Вам не понравится, так как у несовершеннолетних прав по отношению к родителям намного меньше, чем у сотрудников по отношению к работодателю )))

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

Вы же сами писали:

Меня интересует отношение и если оно хорошее и доверительное, то сработаемся, иначе-нет.

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

Вы в своем лицемерии уже запутались )))

руководитель выступает как лидер

Именно так, и его ответственность намного выше, в моем примере - на порядок. Но если Вам так уже нравится считать себя малолетним ребёночком (хотя пора бы повзрослеть), то даже если несовершеннолетний до 14 лет совершит преступление, то отправится на несколько лет в воспитательное заведение закрытого типа. А родители отделаются штрафом и компенсируют материальные убытки. Так что малолетние тоже несут ответственность, хоть и в меньшем размере, чем совершеннолетние. Хотя для меня странно, как, считающего себя малолетним, вообще могут взять на работу. Я бы точно от инфантильной личности, не способной взять на себя ответственность за свои действия, у себя в команде отказался.

Отвечу шаблонно: "ой, всё...")

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

Хех, заплатить 18 млн. за обучение специалиста и отдать его конкурентам. Отличная схема )))

Вот тут тоже разжевано.

Системы управления базами данных, соответствующие 6 классу защиты, применяются ... в информационных системах персональных данных при необходимости обеспечения 3 и 4 уровня защищенности персональных данных.

А тут 4-й уровень защищенности персональных данных - самый низкий.

Для коммерции пофиг на все эти распоряжения.

В терминах Федерального закона от 27.07.2006 N 152-ФЗ, оператор - государственный орган, муниципальный орган, юридическое или физическое лицо, самостоятельно или совместно с другими лицами организующие и (или) осуществляющие обработку персональных данных.

Странно Вы себя ведете. Я Вам все ссылки предоставил, статью, которая разжевывает законы и подзаконные акты предоставил. Вы принципиально не читаете то, на что я ссылаюсь?

РЖД как отрапортовал свой переход на слона, так было опубликовано куча фактов слива персональных данных. И что в итоге? А когда банки сливают данные, какие там штрафы? 10 тыс руб? Даже на Банки.ру смеялись над этим. В общем, мы все не туда идём. Есть закон, а есть жизнь и они не на 100% пересекаются. Я бы даже сказал не сильно пересекаются особенно если хотя бы с одной из сторон есть интерес власти.

И что в итоге?

В итоге ЭТРАН и АСОУП уже месяц как работают на PostgreSQL. Да, косяки есть. Например они нарвались на то, что timestamp в PostgreSQL до микросекунды, а не до 100 наносекунд, что изредка приводило к пропускам документов при запросе только изменений. Вот вчера обновление поставили, в котором обещали эту ошибку исправить.

А когда банки сливают данные, какие там штрафы? 10 тыс руб?

Если бы Вы все же прочитали мою ссылку на КоАП РФ, то такого бы не писали. По части 6, о которой Вы ведете речь, штраф на должностное лицо от восьми тысяч до двадцати тысяч рублей, на юридическое - от пятидесяти тысяч до ста тысяч рублей.

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

Можно возмущаться таким подходом законодателя, можно протестовать или, как Вы, утверждать, что Вас это не касается. Но факт остается фактом. Закон действует сейчас именно в таком виде. И формулировка в части 8 такая, что отсутствие сертификата на используемую для обработки персональных данных базу данных попадает именно под нее.

Что-то не помню, чтобы в новостях так штрафовали банки)

Видать опять: законы одни, в жизни не совсем так.

Поищите Альфа Банк штраф за слив данных.

Вы принципиально не читаете, то что я пишу? Да, по части 6 максимальный штраф для юридических лиц до 100 тыс. рублей. А до 24.02.2021 был до 50 тыс. рублей.

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

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

Извините, но я отказываюсь дискутировать, как только вижу признаки демагогии. В данном случае, явную смену темы. Да еще и с подменой понятий, когда постановление суда о блокировке приравнивается к федеральному закону, включая КоАП и УК.

Ну мы с Вами развели холивар в принципе, отличной от темы публикации. Законы в РФ 100% также работают, как и не работают. Бред? Да, но это жизнь.

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

Ага, от изоляции снимками отказаться. Исправление этого вышло в CU через год одновременно для 2017 и 2019.

Спасибо, что напомнили и ряд системных новых представлений работало неверно. А и иногда почему-то оптимизатор вставлял в запрос на выборку оператор top (10).

Потому да, подождали исправлений и только потом в прод.

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

подождали исправлений и только потом в прод

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

Этим занимаются DBA в основном. Проверяют и после успешной проверки обновляют. Никто не говорил сразу переходить на новую СУБД. Я писал выше, что не откладывать исследовать новую версию и тестировать её.

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

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

Клиент, у которого нет штатного дба и отдела ИБ с тестированием, очень либо бедный, либо вообще далее от ИТ раз доверяет такие вещи сторонним компаниям/людям. 100 млн это не так уж и много. Нет, я писал про крупные компании, которые сами себя всем обеспечивают: и дба, и тестирование, и разработка и часто продажа своих ПО.

крупные компании, которые сами себя всем обеспечивают: и дба, и тестирование, и разработка и часто продажа своих ПО.

И, простите, на какие центры затрат относятся все эти работы и из какого бюджета они покрываются? Это в мелких фирмах может еще быть бардак с финансами. А в остальных предприятиях каждый час работы списывается на конкретный центр затрат и в рамках утвержденного бюджета. Работа любого сотрудника оплачивается. И даже если тот же DBA занимается установкой и поверхностным тестированием новой версии, то значит в это время он не занимался чем-то другим. Возможно более важным. А если этот DBA недостаточно загружен и может позволить себе заниматься тестированием без ущерба остальным проектам, то это вообще ежемесячные убытки для компании.

Тут речь о ситуации, когда на тестах всё "ок", а при внедрении отгребаем кучу проблем.

Либо нагрузки несопоставимые (синтетические тесты не могут правильно нагрузить), либо есть какие-то регламенты, о которых не знают ни разработчики, ни бизнес-аналитики, и поэтому их не протестировали.

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

Значит была плохо проведена проверка и сбор как и что использует. В таком случае в принципе риски высоки даже без обновления.

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

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

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

"опытная эксплуатация"-попахивает гос или около того конторой. В 2017 году от этого отошёл и радуюсь.

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

Даже на относительно простой AX на опытную эксплуатацию, с учетом времени на доработки, уходило 2-3 месяца. SAP и OEBS - уже 3-6.

Системы сложные и высоко нагруженные. Просто Вы не на тех работаете)

Сходите в Каспер, Озон, Яндекс или в мыло на худой конец и посмотрите какие там системы и сколько пользователей и как ведётся разработка, тестирование и внедрение с мониторингом. А потом уже и сами сравните и поймёте, что Ваша "опытная эксплуатация"-средневековье в наше время. Есть понятие непрерывной разработки и доставки кода на разные среды. Это если по русски перевести. По англ называется DevOps и там рисуют в виде бесконечности все этапы.

Вы путаете мягкое с теплым. Вопрос не столько в сложности или высокой нагруженности системы, сколько в стоимости рисков в случае ошибки. Где-нибудь на АЭС - цена этих рисков грандиозна. В РосСетях - огромна. В том же ЕвроХим - очень велика. Например, небольшая ошибка в SCM чревата остановкой непрерывного производства с многомиллиоными затратами. Есть печи, которые можно остановить только один раз. После чего их остается лишь сносить и строить новую.

Да, Вы работаете на госконторы, я понял.

Я на такие компании не работаю.

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

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

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

Да, Вы работаете на госконторы, я понял.

Вы вообще ничего не поняли. В госконторах я внедрял два раза в жизни - в Сбербанке и в ТВЦ. И больше связываться с ними не хочу. В РосСетях внедрение было не в них самих, а в зависимых от них коммерческих компаниях: КамчастскЭнерго, МагаданЭнерго, ТулаЭнерго, ТГК-2. Еврохим, НТК, СГК и СУЭК - вообще частные предприятия. Bunge, где я внедрял SAP на заводах в Днепропетровке и в Воронеже - вообще западная компания. Так же, как McDonalds, где я внедрял на заводе или P&G, где я внедрял логистику в Новомосковске. ММК тоже государственным предприятием не назовешь. Так же, как УралМаш, Истра-Нутриция или уже упомянутый ранее Союзконтракт.

высокой вероятности техногенной катастрофы

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

Коммерческие компании, работающие на гос конторы немного лучше самих этих госконтор.

Остальные-либо заводы, либо предприятия, либо общепит.

Коммерческие компании, работающие на гос конторы

Не понял, что Вы под этим понимаете. В смысле платежей в бюджет и подчинению законам и приказам министерств и ведомств, все коммерческие компании в любой стране работают на государство. Какая разница, подчиняться напрямую министерству, как частные Лукойл или СУЭК, или через РАО ЕС и РосСети, как такие же частные ТГК-2 или СГК?

Остальные-либо заводы, либо предприятия, либо общепит.

Прошу прощения, а кто остался то по Вашему? Или если не купи-продай, то уже госконтора? )))

Озон не работает на гос компании.

Каспер тоже, да у него делают закупки в том числе и госконторы, но сам Каспер делает продукты для всего мира, а не только для госконтор.

А есть компании, которые работают полностью или в основном на госконторы.

Чувствуете разницу?

А есть компании, которые работают полностью или в основном на госконторы.

Да есть. Но я уже писал, за последние 20 лет с такими не сталкивался.

Чувствуете разницу?

Между чем?

Между Bunge и Озон? Первая зарегистрирована в Сент-Луисе (США), вторая в Никосии (Кипр). Это принципиально?

Между ЕвроХим и Лаборатория Касперского? Первая зарегистрирована в Цуг (Швейцария), а вторая в Москве. Вот тут уже разница заметна. И что из этого следует?

После всех проверок в том числе регресса идёт релиз в прод, далее мониторинг, который настроен уже 24 на 7. Все, никакой "опытной" и "тестовой". Просто непрерывный CI\CD процесс.

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

Это отмазка мелких контор, которые пилят госзаказ или около того.

И что? В облако нельзя, так как ФСТЭК приостановил лицензии. Покупают "серые" лицензии только бедные, от безысходности и надеясь, что пронесет. Благо на проверки малых предприятий еще действует мораторий.

И какой смысл бизнесу тратить деньги на переход с проверенной в работе версии на не поддерживаемую? За последние два года ни одного желающего не видел.

Ну да, зачем обновляться. Можно же сидеть и дальше на 2000 версии, все же работает. Такое ощущение, что Вы какой-то завод описываете.

зачем обновляться

Я же писал выше зачем:

"Подавляющее большинство клиентов соглашаются тратить деньги на переход на новые версии только под давлением поставщика, чтобы не остаться без поддержки."

Такое ощущение, что Вы какой-то завод описываете.

Ну если Вы собрались за свои личные деньги обновляться - тогда совсем другой вопрос )))

Можно же сидеть и дальше на 2000

Его поддержка была прекращена лет 15 назад. И если расширенная поддержка (которую уже невозможно купить в РФ) доступна начиная с 2014-го, то базовая поддержка даже для 2017-го уже закончилась в прошлом году.

Потому, как и писал выше, все, что старее 2019 версии, старье.

Это с одной стороны. А с другой противозаконно использовать для обработки и хранения персональных данных более новые версии. Поэтому и переходят мои клиенты на PostgreSQL (точнее, на ее сертифицированные клоны), как на единственную альтернативу MS SQL в РФ.

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

Почему противозаконно? Пруфы в студию плиз

В третий раз? Не теряйте моё уважение, пожалуйста...

Газпромбанк, Альфа, Каспер, маркетплейсы и т д и т п делают и все законно. Грамотные юристы в штате нужны вот и все.

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

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

Кстати, по поводу сертификатов тут все серьезно. Хранить персональные данные в любой версии MS SQL, купленной после марта 2022 года незаконно. В купленной ранее - можно. Но только пока, так как приостановка действия сертификата обратной силы не имеет. Для 2016-го срок истек в августе, но обещали не трогать до конца этого года. Для 2017-го - до конца февраля 2024 года. Для 2019-го - покрыто мраком, так я нашел приостановленный сертификат только для MS SQL Server IoT.

Так что упомянутые Вами крупные компании, рискнувшие перейти на MS SQL 2022, рискуют оказаться дойными коровами для бюджета, выплачивая не хилые штрафы.

А как именно рискуют, если все ПО на своих корпоративных серверах со своим корпоративным облаком?

В зависимости от категории риска, к которой отнесено предприятие, выездная проверка должна производится не реже, чем раз в 2-6 лет.

Я работаю только на коммерцию, никаких военных, гос и полугос контор и никаких контор, работающих на первых трёх. Все прочие поверки проходят успешно и если у компании свое облако и все на своих серверах, то опасности просто физически нет в том числе по персональным данным, т к все они согласно закону на территории РФ.

никаких военных, гос и полугос контор

При чем тут военные или государственные предприятия критической инфраструктуры, где MS SQL вообще никогда недопустимо было применять? Там требуется хотя бы 4 уровень доверия, а MS SQL никогда не получал выше 6-го.

в том числе по персональным данным, т к все они согласно закону на территории РФ.

Этого недостаточно. Не буду давать ссылки на законы и подзаконные акты ФСТЭК, так как явно видно, что Вы в этом плохо ориентируетесь. Ограничусь статьей на cnews.

Обязательная сертификация средств защиты информации касается:

  • [...]

  • персональных данных (ЗПДн);

  • автоматизированных систем управления технологическим процессом (АСУ ТП);

  • [...]

  • конфиденциальной (служебной) информации.

Запрещается использование несертифицированного продукта в сферах, предусматривающих обязательное применение систем, прошедших сертификацию.

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

А тем временем в системах реального времени по слежению за движением судов СУБД на всех объектах стоит какая? Правильно-скуль)

И все там по сертификации и по безопасности норм в том числе и после обновлений.

Я даже Вас ещё сильнее удивлю, но даже в решениях таких гигантов как Касперский стоит скуль, потому что слон даже который про просто не выдерживает таких нагрузок.

Я уже писал выше, что закон обратной силы не имеет. Если они успели до марта 2022 года обновиться до MS SQL 2019 (предположим, что был сертифицирован не только IoT, хотя я этого не нашел), то у них есть время до 10.02.2026 для перехода на PostgreSQL.

И все там по сертификации и по безопасности норм в том числе и после обновлений.

С обновлениями (CU) уже хуже. Судебная практика по этому вопросу еще не устоялась. Ждем решения ВС РФ.

слон даже который про просто не выдерживает таких нагрузок.

"Вы просто не умеете его готовить" (с) )))

Мне еще ни разу не попался такой запрос или даже хранимая процедура, которую при переносе с MS SQL на PostgreSQL нельзя было бы оптимизировать так, чтобы производительность оказалась если не лучше, то уж точно не хуже, чем в MS SQL.

Ну да, если в хранимке нафигачить десятки временных таблиц, а заполнять каждую из них не только INSERT, а еще и множественными UPDATE, то результат переноса такого кода без рефакторинга на PostgreSQL вполне предсказуем.

Лучше в слоне? У меня даже один результат сравнения опубликован, когда слон настраивали адепты слона, а скуль мы. И что-то слон проиграл. Это было для 1С. Уже давно слона пытаются продвинуть те, кто хочет на этом заработать. Но факт остаётся фактом слону далеко до скуля. Я неск раз в год делают сравнение. Только одно исследование опубликовал с детализацией всех настроек. Небольшие системы можно на любую СУБД перенести, а вот кровавый Энтерпрайз нет, хотя уже какой год пытаются частями перейти.

Лучше в слоне?

Да. Благодаря массивам, композитным типам, JSONB, нежурналируемым таблицам, pg_variables, INSERT/UPDATE/DELETE ... RETURNING в CTE, намного более развитым индексам и т.п.

В ряде случаев, просто благодаря plr или plpythonu, производительность решения оказывалась на порядок выше. Это камень в сторону жутко медленного sp_execute_external_script.

А насколько CDC в MS SQL медленней и тяжелей в поддержке, чем REPLICATION SLOT через WAL в PostgreSQL? На глаз видно, насколько Debezium меньше грузит сервер на PostgreSQL, чем на MS SQL.

Главное преимущество MS SQL в более развитом оптимизаторе запросов, что снижает требования к квалификации разработчика и расширяет применимость ORM. Вот тут соглашусь, что написание оптимального кода для PostgreSQL обходится дороже, чем для MS SQL. Достаточно только вспомнить skip index scan, который до сих пор не всегда работает и в который PostgreSQL нужно загонять пинками. Собственно говоря, именно меньшая стоимость разработки - самая главная причина того, что MS SQL популярней PosrtgreSQL.

Это было для 1С.

Так проблема тут именно в 1С. Там даже рефакторинг не поможет, так как 1C пока не способна использовать то, что я перечислил в предыдущем абзаце. А уж её страсть лепить временные таблицы на любой чих противоречат идеологии временных таблиц в PostgreSQL. Так же как многократные UPDATE одной таблицы в одной обработке.

вот кровавый Энтерпрайз нет, хотя уже какой год пытаются частями перейти.

Расскажите это РосАтому, РосСетям, Почте России или даже РЖД. Они очень удивятся )))

Вот уж с MS SQL и Oracle на PostgreSQL - есть целый ряд успешно завершенных проектов для ЕвроХим, СГК, НТК и СУЭК. Есть даже с шардированием и мультимастером. Вот что делать с SAP и Hana - это уже большой вопрос, ответа на который пока нет. 1С тут точно не вариант. Скорее уж Галактика.

Галактика? Все, остановимся.

Про слона останусь при своем мнении, основанном на опыте.

Предлагаю закрыть тему, т к мы далеко ушли от темы публикации.

Галактика?

А Ваши предложения? SAP, OEBS и AX ушли с рынка. Остались, по сути, только 1С, «Галактика», «Парус» и «Компас».

Сколько я ни сталкивался с 1C - это ужас из сто-пятсот интеграций между ними, которые постоянно отваливаются. Даже на небольшом часовом заводе было полтора десятка инсталляций, так как в централизованном виде оно вообще не шевелилось. Учет содержания драгметаллов в каждой единице продукции для 1C оказался фатален. Для Enterpise синхронная разноска документов, как в 1С, вообще не пригодна. Только как в SAP или OEBS - отправил документ в разноску и через пару минут узнал, разнесся он или есть ошибки. Вот и получается, что к текущим реалиям легче всего адаптироваться Галактике. Даже не смотря на то, что по функционалу она от 1С отстает, её платформа предоставляет больше свободы для адаптации к СУБД.

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

1С оставить для бухов

А так и есть в подавляющем большинстве случаев. Но для IPO 1C уже никак не подходит. Поэтому, в качестве ERP до сих пор лидируют SAP, OEBS и AX.

доверить собственной разработанной системе

Это намного, на порядки дороже, чем внедрение ERP. Я даже затрудняюсь сказать, за сколько миллиардов рублей обойдется самописная ERP, например, для ЕвроХим. Вы хоть представляете себе, что такое поточное производство с детализированным учетом затрат. Да там только декларация об экспортном НДС с приложениями сложнее, чем упомянутая Вами "система реального времени по слежению за движением судов".

Причем я знаю о чем говорю, так как принимал непосредственное участие в разработке системы реального времени по слежению за движением вагонов по колее 1520. Вы уж простите, но вагонов намного больше, чем судов. И информации по ним стекается намного больше. Чего только стоят осмотры с замерами износа каждого колеса.

Как минимум такие системы есть у Сбера, Альфы, МТС и Озон.

Сбер - SAP, Альфа - SAP, МТС - SAP

И что Вы хотели сказать? Что какие-то, намного более простые задачи, чем ERP, они решают собственными разработками? Ну так это не новость.

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

В системе реального времени нет проверок про колеса, это не туда.

Вас не спросили?

чтобы не было аварии при движении

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

С судами все сложнее.

Как раз с судами проще, так как у них нет выделенных путей, где избежать столкновений намного сложнее, чем на воде. Но, впрочем, тут меня интересуют именно вагоны, а не поезда. Поезда уже забота самой РЖД.

Какие миллиарды? Если внешников подключать, то да дорого, а так как всегда 3-6 месяцев и несколько лямов рублей, чтобы предоставили рабочий прототип. Затем этот прототип доводится до ума для внутреннего использования или выставляется на продажу и допиливается на деньги заказчиков. Во втором случае продукт будет дорогой, т к будет учитывать хотелки заказчиков. В первом недорогой, т к только для конкретных задач одной компании.

Ну напишите хотя бы постановку на что-то вроде SAP MM за 3-6 месяцев, силами команды из нескольких десятков человек. А если уж речь о заводах по производству минеральных удобрений, то нужны еще, как минимум, FI, CO, FSCM, LE, PP, QE и PM.

Тут внедрение длится 2-3 года, а Вы собрались за 3-6 месяцев разработать готовую систему? SAP в рекламных материалах пишет о полутора годах на внедрения и 42 тыс. человекочасах. Даже при весьма скромном ФОТ (не зарплате!) в размере 200 тыс. рублей на одного человека в месяц (160 часов), это получается свыше 50 миллионов рублей. Это только внедрение, без обучения персонала, тестирования и опытной эксплуатации! Сама система поставляется готовой. На практике, не слышал о бюджете на внедрения SAP меньше 100 миллионов рублей. В среднем - внедрение SAP обходится в $2,55 миллионов. Пересчитайте по текущему курсу.

Потому что не надо мерить по сап.

В реалиях примерно так и дают: 3-6 мес и небольшую сумму, далее как хочешь, но сделай прототип хоть один сам и продай. Смог? Отлично-привлек деньги заказчиков или компании, для которой делал прототип. Нет-значит нет.

Есть достаточно много небольших решений и хороших и недорогих. Да, они все на свете не решают, но и не стоят столько, сколько сап.

Потому что не надо мерить по сап.

Почему вдруг Вы настаиваете на смене темы? Мы же обсуждали совершенно конкретный пример:

"Я даже затрудняюсь сказать, за сколько миллиардов рублей обойдется самописная ERP, например, для ЕвроХим."

А там как раз внедрен SAP, да еще и с существенно большим набором модулей, чем я перечислил.

Потому что думают, что купить готовое проще. Не проще! Особенно кастомизация, внедрение и сопровождение. Проще свою маленькую систему для конкретных нужд написать. И нет там ничего сложного. Если надо люди пишут собственный сборщик мусора для памяти. Да если надо люди даже пишут собственные ограниченные СУБД. Хотя вот свой оптимизатор запросов написать это да-это уже уровень учёных. А все прочее ну или почти все-просто ремесло и нет там ничего выдающегося. Просто ловкость рук, уровень экспертизы в предметной области и тоже самое в технологиях и языках программирования, умение быстро находить нужных людей, выстраивать рабочие и коммуникационные процессы и т д и т п.

Ерп не вершина сложности ИТ-систем. Система сложная только потому, что берут готовую с кучами ненужных функций и модулей и пытаются натянуть на свои задачи. Все равно, что космический корабль переделывать в автомобиль. Проще автомобиль сделать с нуля в таком случае. И суммарно будет многократно дешевле.

Потому что думают, что купить готовое проще. Не проще!

То есть руководство подавляющего количества предприятий в мире дебилы, не понимающие, что дешевле разработать систему самому, чем купить и внедрить?

Даже двойку Вам по экономике не могу поставить. Только жирный кол. Разрабатывать систему самому рентабельно либо на продажу, либо если альтернативы ей на рынке просто нет.

Ерп не вершина сложности ИТ-систем.

А я этого не говорил. Просто я хорошо ERP знаю. Я даже когда-то, чуть больше, чем за год, для Союзконтракта (окорочка летят) командой из восьми человек разработал и внедрил "маленькую систему для конкретных нужд" - Модуль "Продажи и дистрибьюция" к Platinum ERP. Финансы, SCM, MM и планирование тогда внедрены уже были почти без доработок. А вот SD под их требования переписывать пришлось почти полностью.

Главная сложность ERP в том, что она очень тесно связана с человеческим фактором и уникальными на каждом предприятии бизнес-процессами, которые еще и обладают свойством изменяться со временем. В том числе под воздействием изменяющегося законодательства. Отсюда и требования к максимальной универсальности используемых алгоритмов и просто огромному количеству настроек.

свой оптимизатор запросов написать это да-это уже уровень учёных

Производители ERP, особенно SAP, тоже самое утверждают о многих используемых в нем алгоритмах. Я уже не говорю об обилии их патентов.

Да, большинство управленцев некомпетентны в ИТ, потому и покупают кактус, жуют, страдают, но жуют.

Может закончим?

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

Предлагаю Вам самим написать реляционную СУБД лучшую, чем PostgreSQL и MS SQL вместе взятые. А то ведь, дураки покупают Postgres Pro Enterprise Certitfied за целые 180 тыс. рублей. Вы же считаете, что написать самому дешевле?

Или Вы, хоть немного, разбираетесь в СУБД и способны понять, сколько денег потребуется вложить в такую разработку? А то, в чем не разбираетесь вообще, считаете таким простым, что написать можно за 3-6 месяцев?

Вот я взял самый маленький проект из текущих. Просто трансформация бизнес данных для оптимизационной модели планирования (Gurobi) с собственной веб-мордой для настроек и визуализации результата оптимизации. 100 МБ кода. Преимущественно - C#. Анализ GIT показывает, что в среднем один программист за день выдавал туда 5-10 КБ кода (100-200 строк кода на C# в день - очень даже неплохо!). Берем максимум. Получаем 10 тыс. человекодней или 500 человекомесяцев. Знаю, что занизил, так как не учел отпуска и то, что какой то код переписывался по несколько раз. Среднюю зарплату берем всего в 200 тыс. в месяц. Затраты на человека получаются уже 300 тыс. в месяц с учетом налогов, нормы прибыли и скромными управленческими затратами (66% на руки - это очень много). Судя по JIRA, аналитики на постановки списывают в этом проекте даже больше, чем разработчики. Ну пусть будет столько же. Итого, себестоимость этой маленькой системы составляет уже 300 миллионов рублей. Если бы такая система была уже готовая на рынке, то купить её можно было бы меньше, чем за миллион и еще за 29 миллионов спокойно внедрить. Разница на порядок.

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

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

А так если надо-советую скуль покупать либо тратить также много денег на спецов, которые из опенсоурс решений сделают вам как надо+за поддержку и мониторинг. Везде платно будет и ещё вопрос где дороже.

Как-то частично усваиваете то, что я пишу. Про СУБД как раз я писал, что оптимизатор свой написать-это уровень учёных, а потому сложно. Ерп - систему на коленке написать можно

Как раз очень хорошо усвоил. Про сложность СУБД Вы в курсе, поэтому сразу возводите ее на уровень ученых. А про сложность ERP - не в курсе, поэтому считаете, что можно написать её на коленке. Даже не подозревая что наукоемкость там намного выше, чем в СУБД, и принижая EPR до уровня учетной системы. А ведь ERP - это Enterprise Resource Planning (планирование ресурсов предприятия). И главная зада ERP не учет, а оперативное и долгосрочное планирование всех ресурсов: трудовых, материальных, капитальных, закупок, сбыта, логистики и т.п. И на эту тему научных трудов написано на порядки больше, чем про оптимизаторы СУБД. Я же дал Вам ссылку на тысячи патентов только SAP. Опять проигнорировали?

Зачем покупать постгресс про, если есть бесплатный слон

По двум причинам.

Во-первых, потому, что для поддержки PostgreSQL Вам потребуется разработчик, способный разрабатывать патчи к PostgreSQL и продвигать их на CommitFest, чтобы потом не кувыркаться при обновлении на следующую версию. Или Вы рискуете нарваться на ошибку в коде PostgreSQL, которую community не исправит годами, потому что случай, в котором она проявляется, слишком редкий и среди пользователей PostgreSQL критичен только для Вас. В свою очередь, Postgres Pro такие ошибки в рамках купленной поддержки исправляют весьма оперативно и сразу форсируют PR в mainstream. Только в сентябрьском и ноябрьском CommitFest я насчитал по четыре исправления ошибок (именно Bug Fixes!) от сотрудников Postgres Pro. Часть из них до сих пор не закоммичена в PostgreSQL, но наверняка уже в Postgres Pro. Итого, при стоимости поддержки от Postgres Pro при покупке ее сразу на три года в 45 тыс. рублей в год, Вы каждый месяц будете платить своему специалисту намного больше. Только чтобы он был. Если считать на пять лет то покупка и поддержка Postgres Pro Enterprise Certified обойдется в 80 тыс. в год, что, примерно столько же, сколько 40 часов работы middle разработчика за этот же год. А ведь этого мало даже только для того, чтобы ориентироваться в актуальном коде PostgreSQL.

Во-вторых, если СУБД требует сертификации, хотя бы из-за хранения в ней персональных или служебных данных, то свой экземпляр PostgreSQL Вам потребуется сертифицировать за свой счет. Мало того, что стоимость такой сертификации начинается от 2 млн. рублей, так еще и ждать её потребуется 9-12 месяцев.

советую скуль покупать

Советовать Вы, конечно, можете, но рынок решений, где можно обойтись без сертифицированной СУБД очень узок. Поэтому я Вам советую забыть об MS SQL, и заняться PostgreSQL.

Так, стоп! В ерп есть что-то сложное на уровне оптимизатора запросов?

Намного сложнее. Оптимизация поставок, логистики, производства, сбыта и складских запасов для достижения локальных минимумов послойных целевых функций. Например в SAP IBP для этого интегрирован Gurobi. В OEBS свой самописный оптимизатор.

Выше я упоминал расчет COGS для оптимизации экспортного НДС. Там не сильно проще и он тоже в SAP на Gurobi.

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

А как Вы еще представляли Enterprise Resource Planning? Планирование без оптимизации что ли? Ну так это прошлый век и называлось MRP.

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

ERP — организационная стратегия интеграции производства и операций, управления трудовыми ресурсами, финансового менеджмента и управления активами, ориентированная на непрерывную балансировку и оптимизацию ресурсов предприятия посредством специализированного интегрированного пакета прикладного программного обеспечения, обеспечивающего общую модель данных и процессов для всех сфер деятельности

Тогда это все эмпирические задачи, а между ними нет понятия сложнее/легче, ибо они не имеют полностью подходящего решения. И такие задачи сложные, да. Но все остальное вполне реализуемо и достаточно быстро.

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

Вторая сложность - это трансформировать имеющиеся в БД учетные данные и прогнозы в систему линейных и нелинейных уравнений и неравенств, которые уже можно подавать на вход solver (нет устоявшегося перевода; пример, тот же Gurobi). И обратная задача, произвести уже дискретную оптимизацию решения solver и преобразовать результат в понятные бизнесу данные.

Но все остальное вполне реализуемо и достаточно быстро.

Не понял, что "остальное", если главная цель ERP непрерывная балансировка и оптимизация ресурсов предприятия? И если Вы будете делать учетную систему, то к этой цели Вы почти не приблизитесь. Вы только получите коллектор сырых данных. Уже на уровне разносок требуется все время держать в уме, как эти данные должны использоваться дальше. Иначе непрерывной балансировки и оптимизации не получите.

Вы так интересно отвечаете, спасибо! Предлагаю написать публикацию об этом. Что скажите? Думаю всем будет интересно почитать. Плюс обмен опытом, кто в ерп живёт через комментарии.

Боюсь, это слишком большая тема для одной публикации. Это уже тема для книги. Тут надо как-то на более мелкие части это разбивать. Тут только дискретка уже может потянуть на серию статей. Про то как не исказить результат оптимизации, но избежать полутора землекопов и четверти экскаватора )

Тем более! Начните серию статей, а там может и книгу выпустите.

То есть руководство подавляющего количества предприятий в мире дебилы, не понимающие, что дешевле разработать систему самому, чем купить и внедрить?

Всё сильно зависит от ситуации. Писать новую ERP под миллионную компанию безумно. Но если ERP/CRM/etc росла вместе с компанией несколько десятилетий, то и подобрать ей замену невозможно. Потому что и начальники всех уровней, и простые пользователи, настолько привыкли, что удовлетворяют их малейшие хотелки - кнопку перекрасить, или пункты меню местами поменять, не говоря уже о возможности внедрения больших процессных изменений, что просто не могут жить иначе, и от покупной системы уйдут в забастовку в первый же день.

подобрать ей замену невозможно

Спуститесь с небес. Даже такой монстр, как МТС перешел с OEBS на SAP. Все возможно.

Я уже больше 30 лет внедряю. И каждый раз - это не совершенно новое предприятие, а компания, у которой уже есть своя система учета и которая понимает, что без внедрения новой системы ей не обойтись. Было бы по Вашему, рынок ERP давно сдулся, так как новых клиентов просто не стало. Не будем брать последние годы с их взрывным ростом рынка ERP из-за СВО. В 2021 году рынок ERP в РФ составил свыше 100 млрд. рублей. Свыше 40% занял SAP. При средней стоимости внедрения SAP в 200 млн. рублей, это получается 400 внедрений за год. Вы действительно думаете, что это столько новых крупных(!) предприятий в РФ появилось за год?

удовлетворяют их малейшие хотелки - кнопку перекрасить, или пункты меню местами поменять

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

А условная тетя Маня на складе или дядя Вася в цеху может уволиться

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

Вероятно, у вас получается внедрять там, где на эффективность вообще положить. Главное, что сказали в высоких кабинетах, и вся иерархия взяла под козырёк и побежала делать. А что получится, кого волнует - мы тут исполняем приказ сверху.

Так и поступают в госконторах или около них, что работают на них.

В моём примере прислушиваться будут к менеджерам в середине иерархии

В середине - естественно будут. Директора филиалов, начальник производства или департамента имеют права голоса. Даже к начальнику цеха, скорее всего, прислушаются. А вот мастера или начальника отдела/участка - уже вряд ли станут особо слушать. А на уровне исполнителей - точно не прислушаются.

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

С точностью наоборот. В основном это промышленные предприятия, где те, от кого зависит эффективность и есть руководители высшего и среднего звена. Есть редчайшие исключения в виде уникальных мастеров или начальников отделов. Но это не те люди, которые станут просить поменять цвет кнопочки. Людей, утверждающим, что эффективность их работы зависит от цвета кнопочки, можно встретить либо среди исполнителей, которых всегда можно заменить, либо среди топ-менеджмента, где уже "любой каприз за их деньги" )

В общем случае, мне, как внедренцу, только выгодны подобные пожелания. Они существенно повышают доходность проекта и позволяют затягивать сроки. Ведь каждая группа таких хотелок - либо отдельный бюджет с планом, либо допсоглашение со спецификацией. Чем дороже и дольше проект - тем меньшую часть в затратах на него составляет комплектация проектной команды и её обучение.

когда слон настраивали адепты слона, а скуль мы

Поделитесь информацией, в каком режиме обычно экплуатируют большие базы. Стандартный блокировочник, или новый версионник (READ_COMMITTED_SNAPSHOT, ALLOW_SNAPSHOT_ISOLATION)

Первое очень больно в разработке, особенно если переходить с других СУБД - залоченные записи после чтений просто кошмар. На втором у нас не хватает производительности, если базы под 10ТБ.

Версионник и он уже больше 10 лет как не новый. Я работаю в том числе с базами, размер которых превышает 2 ПБ, и в них есть таблицы свыше 100 ТБ.

Именно версионник на 2ПБ?

Практически нереально сделать большой update, хотя частями в разных транзакциях выходит на порядок быстрее.

Но вот

alter table add column not null default 0

похоже начинает делать копию таблицы в версии. Когда через час это надоедает ждать, жмём отмену, и он ещё часов 20 начинает откатывать из версий. Тут только ждать - физическая перезагрузка сервера начинает операцию заново.

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

В enterprise версии SQL Server добавление колонки с default'ом - операция над метаданными и без dataflow.

То есть, они специально ухудшают алгоритмы в версии Standard, чтобы было за что платить? Я бы ещё понял, если бы фичи не было. Но такое...

Почему ухудшают? Просто лучшая версия в более дорогой редакции.

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

Простите, вы не читаете

...если нужна бизнес дата - пожалуйста, храните в той же таблице отдельной колонкой.

Про Ledger таблицы - я просто рассказал, что есть такой функционал из "коробки". Если вам показалось, что мне интересен вопрос о сложностях с лицензированием - отнюдь.

Простите, вы не читаете

Это Вы не читаете. Зачем мне тепоральная таблица, если я должен хранить даты отдельной колонкой и мне вообще ни к чему служебные поля ValidFrom и ValidTo? Мне совершенно не интересно, когда началась транзакция во время которой эта запись попала в БД.

Как обычно, MS формально выполнил требования стандарта SQL:2011, окрестил system-versioned tables темпоральными, и вместо текущего времени запихнул туда время начала транзакции, что приводит к сложностям доступа к записям с одинаковым ключом, вставленных в одной транзакции. Еще и IDENTITY поле приходится добавлять, чтобы можно было хотя бы в однозначном порядке их выбирать.

Спасибо, покувыркались, больше не хочется.

Тяжело иногда с теми, кто не хочет слышать. Идём и курим, что такое index density и как она связана с cardinality.

Я не предлагал IsDeleted вносить в индекс, читайте внимательнее. Я говорил, что строить индекс по колонке в которой всего 2 уникальных значения это дурь сама по себе, если уж у вас так сильно перекошенны данные, что одного значения 10%, а другого 90, то по 10% надо строить именно фильтрованный индекс и не страдать историями про частичное покрытие.

надо строить именно фильтрованный индекс

Ну если бы Вы удосужились читать, то что я пишу, то именно эту рекомендацию от меня бы и увидели )))

Я слова "фильтрованный" не увидел в вашем посте вот совсем

В SQL частичный индекс, который Вы назвали "фильтрованный", это индекс с выражением WHERE, что я и написал изначально:

"А вот использовать в в условиях фильтрации и соединении слева выражение, полностью совпадающие с выражением в WHERE частичного индекса - очень хорошо."

"индекс (a,b) WHERE IsDeleted=0"

В документации есть понятие фильтрованного индекса, а не частичного в данном случае.

А в стандарте употребляется словосочетание "partial index". Так что, если Вам это мешает, пишите MS, чтобы соответствовали стандарту )

Не нашел, где скачать свежий стандарт. До 2011 года включительно индексы вообще не стандартизировались. Предлагаю пока удовлетвориться тем, что я не знаю ни одной СУБД, кроме MS SQL, где частичные индексы назывались бы фильтрованными. В Hana, PostgreSQL, Informix, SQLite, YugobyteDB, MongoDB и даже в django употребляется термин "partial index". Ну а при стандартизации работает правило большинства.

В принципе, с точки зрения семантики, "частичный индекс" намного лучше описывает результат применения выражения WHERE при создании индекса. Все же индекс строится не по всей таблице, а лишь по ее части, отфильтрованной выражением. Тогда как термин "фильтрованный индекс" приводит к когнитивному диссонансу. Ведь сам индекс никак не фильтруется. Фильтруются данные в таблице при построении индекса, а вовсе не индекс. Тогда уже надо было бы писать"индекс по фильтрованным данным"

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

Бэкапы на англ, на русском-резервные копии. И т д

По английски тогда "filtered data index". Но "partial index" лаконичней.

индекс с фильтром или фильтрующий индекс

"index with filter" или "filter index" - опять хрень.

Машинный перевод на MS перевел, как "отфильтрованные индексы", несмотря на то, что фильтруются данные для индексации, а вовсе не сами индексы. И что Вы хотели этим сказать?

Это не машинный перевод. При машинном переводе прямо пишут, что это машинный перевод. Еще раз почувствуйте разницу: частичный/кусочный индекс или индекс с фильтром/фильтрующий индекс. Второе сразу понятно что это, а первое? Нужно переводить на язык по смыслу. Или Вы и здесь спорить будете?

При машинном переводе прямо пишут, что это машинный перевод

Окс, но на самом деле на русском и правда пишут не частичный, а фильтрованный индекс или индекс с фильтром: https://sql--ex-ru.turbopages.org/turbo/sql-ex.ru/s/blogs/?pcgi=%2FFiltrovannye_indeksy.html

Даже в переведенной студии SSMS на русском и даже в книге по подготовке к сертификации MS SQL 2012. Да много где, только здесь первый раз встретил фразу "частичный индекс".

У переводчиков MS свой словарик. Например, мне было трудно привыкнуть к "секционированию", когда оно всегда было калькой с английского "партиционированием". Стараюсь избегать русских версий, что Visual Studio, что SSMS (одно только "Строй всё" чего стоит...)

А причем тут переводчик MS? Секционирование - это перевод на русский в принципе, а "партиция" такого слова просто нет в русском языке.

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

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

Получилось так, что мы друг-друга не поняли (хотя говорили об одном и том же) - бывает. Не думал что это вызовет такой сильный резонанс, sry.

Тоже в основном использую англ версии ПО в работе, кроме ОС на ноуте. Просто когда англ слова пишут русскими буквами-режет глаза и слух.

В п.49 ошибка: "Не рекомендуется использовать синтаксис в виде бесконечного цикла и одного FETCH’а".

Он должен звучать КАТЕГОРИЧЕСКИ РЕКОМЕНДУЕТСЯ использовать! Поясню о чем речь. Этот "полуторный цикл" кстати придумал не абы кто, а Стивен Макконнелл в Книге Совершенный Код. Так вот:

WHILE (1=1)

BEGIN

FETCH cursorname INTO vars

IF @@FETCH_STATUS <> 0 BREAK;

Здесь делаем дело

END

Чем этот код прекрасен:

  1. Один вход в цикл и только один выход из него (где BREAK)

  2. Вы используете только один раз FETCH.

Так что мелочиться то, сразу goto делать вместо всех циклов for и while во всех языках программирования. Удобно для унификации.

Кстати, не напомните номер страницы книги, где упоминается именно о том, что Вы написали?

Макконел называет это loop-and-a-half. Вот книжка: http://aroma.vn/web/wp-content/uploads/2016/11/code-complete-2nd-edition-v413hav.pdf

На картинке немного запутанно. Но смысл в том, что при обычно цикле приходится FETCH cursorname INTO vars делать ДО цикла, а потом еще раз В цикле. А подход "полуторный цикл" убирает необходимость дублирования этой части кода. Насчет goto он вам отвечает на две страницы выше)))

Еще 40 лет назад доказали, что при использовании такой цикл более понятен и программисты реже "лажают", чем пытаясь писать условие в while и дублировать часть кода до и внутри цикла.

С Наступающим новым годом! И уважением.

Вас тоже с праздниками! Данный пример для си-языков, а здесь мы T-SQL рассматриваем. И не смотря на почетную книженцию, в данном примере есть риск, что из цикла можно вообще никогда не выйти. Т е не смотря на авторитет автора и с учетом риска бесконечного зацикливания кода, позволю себе не согласиться. Может раньше так и было можно, а сейчас больше за предсказуемый по выполнению и безопасный код.

Данный пример опасен тем, что можно просто ошибиться и никогда не выйти из цикла

Ошибиться и у вас можно.
Например, если внутренний FETCH NEXT попадёт под действие какого-то IF

Идеальный синтаксис - в firebird:

FOR SELECT x, y, z FROM t 
INTO :x, :y, :z do
BEGIN
  -- any
END

Вам везёт в том, что в вашей организации вы самый авторитетный SQL разработчик, и никто с вами не спорит. Был бы у вас второй SQL-синьор, который бы топил за Макконнелловский паттерн цикла, сколько вы бы друг другу нервов потрепали )))

Я не самый авторитетный и мы часто обсуждаем и спорим особенно на ревью решения. Мы просто не ставим авторитетов выше себя: всегда все перепроверяем. В данном случае, книга хорошая, но местами её подходы естественным образом устарели. И добавлю (уже где-то писал): любая книга/публикация и т д есть отражение опыта его/её автора/авторов, а значит заранее ограничена именно опытом конкретных специалистов. Т е где-то материал будет полезен, а где-то не очень. А общая унификация вообще может жить только в вакууме и в реалии весьма вредна. И книги авторитетов не являются исключением.

Ладно еще синьор, а если архитектор с сорокалетним опытом, начиная с DB2 на ЕС ЭВМ, как я? )))

Я в коде избегаю потенциально бесконечные циклы. Если быть более конкретным, то в похожем случае уже не раз отказывался утверждать PR, увидев OPTION(MAXRECURSION 0) в запросе. И что будет с таким запросом в Вашем цикле? Вот до сих пор не пойму, для кого такую опцию придумали.

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

Articles