Все мы, кто работает с реляционными базами данных, узнали (или изучают), что SQL отличается. Чтобы добиться желаемых результатов и сделать это эффективно, требуется утомительный процесс, отчасти характеризуемый изучением незнакомых парадигм и обнаружением того, что некоторые из наших наиболее знакомых шаблонов программирования здесь не работают. Какие общие антипаттерны вы видели (или сами совершали)?
sql
anti-patterns
le dorfier
источник
источник
Ответы:
Меня постоянно разочаровывает тенденция большинства программистов смешивать свою UI-логику на уровне доступа к данным:
Обычно программисты делают это, потому что они намерены привязать свой набор данных непосредственно к сетке, и просто удобно иметь формат сервера SQL Server, а не формат на клиенте.
Запросы, подобные приведенному выше, чрезвычайно хрупкие, поскольку они тесно связывают уровень данных с уровнем пользовательского интерфейса. Кроме того, этот стиль программирования полностью предотвращает повторное использование хранимых процедур.
источник
Вот мой топ 3.
Номер 1. Невозможность указать список полей. (Изменить: для предотвращения путаницы: это правило производственного кода. Оно не применяется к одноразовым сценариям анализа - если я не автор.)
должно быть
Номер 2. Использование курсора и цикла while, когда будет использоваться цикл while с переменной цикла.
Номер 3. DateLogic через строковые типы.
Должно быть
Я видел недавний всплеск «Один запрос лучше, чем два, верно?»
Этот запрос требует двух или трех разных планов выполнения в зависимости от значений параметров. Только один план выполнения генерируется и помещается в кеш для этого текста SQL. Этот план будет использоваться независимо от значения параметров. Это приводит к периодической низкой производительности. Гораздо лучше написать два запроса (по одному на каждый план выполнения).
источник
Удобочитаемые поля пароля , например. Самоочевидно.
Использование LIKE против индексированных столбцов, и я почти испытываю желание просто сказать LIKE в целом.
Переработка сгенерированных SQL значений PK.
Сюрприз, никто еще не упомянул бог-таблицу . Ничто не говорит «органично», как 100 столбцов битовых флагов, больших строк и целых чисел.
Затем есть шаблон «Я скучаю по INI-файлам» : хранение CSV- файлов , строк с разделителями каналов или других необходимых для анализа данных в больших текстовых полях.
А для MS SQL server использование курсоров вообще . Есть лучший способ сделать любую заданную задачу курсора.
Отредактировано потому что так много!
источник
LIKE '%LIKE'
.Не нужно копать для этого: не использовать подготовленные заявления.
источник
Используя бессмысленные псевдонимы таблиц:
Делает чтение большого оператора SQL намного сложнее, чем нужно
источник
источник
Мои ошибки - это таблицы доступа из 450 столбцов, которые были собраны 8-летним сыном лучшего друга-управляющего собакой-распорядителем и изворотливой справочной таблицы, которая существует только потому, что кто-то не знает, как правильно нормализовать структуру данных.
Как правило, эта таблица соответствия выглядит следующим образом:
Я потерял счет количества клиентов, которых я видел, у которых есть системы, которые полагаются на подобные мерзости.
источник
Больше всего мне не нравятся
Использование пробелов при создании таблиц, sprocs и т. Д. Я в порядке с CamelCase или under_scores, а также в единственном или множественном числе и UPPERCASE или в нижнем регистре, но при этом необходимо ссылаться на таблицу или столбец [с пробелами], особенно если [это странно разделено] (да, Я столкнулся с этим) действительно меня раздражает.
Денормализованные данные. Таблица не должна быть полностью нормализована, но когда я сталкиваюсь с таблицей сотрудников, которая имеет информацию об их текущем оценочном балле или их первичном чем-либо, это говорит мне, что мне, вероятно, нужно будет создать отдельную таблицу в какой-то момент и затем попытайтесь синхронизировать их. Сначала я нормализую данные, а затем, если увижу место, где помогает денормализация, я рассмотрю это.
Злоупотребление либо представлениями, либо курсорами. Представления имеют цель, но когда каждая таблица упакована в представление, это слишком много. Мне приходилось использовать курсоры несколько раз, но обычно вы можете использовать другие механизмы для этого.
Доступ. Может ли программа быть анти-паттерном? У меня есть SQL Server в моей работе, но многие люди используют доступ из-за его доступности, «простоты использования» и «дружелюбия» для нетехнических пользователей. Слишком много здесь, чтобы вдаваться, но если вы были в подобной среде, вы знаете.
источник
используйте SP в качестве префикса имени хранимой процедуры, потому что он будет сначала искать в расположении системных процедур, а не в пользовательских.
источник
Чрезмерное использование временных таблиц и курсоров.
источник
Для хранения значений времени следует использовать только часовой пояс UTC. Местное время не должно использоваться.
источник
используя @@ IDENTITY вместо SCOPE_IDENTITY ()
Цитируется из этого ответа :
источник
Повторное использование «мертвого» поля для чего-то, для чего оно не было предназначено (например, хранение пользовательских данных в поле «Факс») - хотя это очень заманчиво в качестве быстрого решения!
источник
и предполагая, что результат будет отсортирован по some_column. Я видел это немного с Sybase, где предположение верно (пока).
источник
Или втиснуть все в одну строчку.
источник
FROM TableA, TableB WHERE
Синтаксис JOINS вместоFROM TableA INNER JOIN TableB ON
Предположение, что запрос будет возвращен, отсортировано определенным образом, без добавления предложения ORDER BY, просто потому, что так оно и было во время тестирования в инструменте запросов.
источник
Изучать SQL в первые шесть месяцев своей карьеры и никогда больше ничего не изучать в течение следующих 10 лет. В частности, не учиться или эффективно использовать оконные / аналитические функции SQL. В частности использование over () и разделение по.
См. Приложение A O'Reilly SQL Cookbook для хорошего обзора оконных функций.
источник
Мне нужно поместить свой текущий любимый здесь, просто чтобы завершить список. Мой любимый антипаттерн не проверяет ваши запросы .
Это относится, когда:
И любые тесты, выполненные против нетипичных или недостаточных данных, не учитываются. Если это хранимая процедура, поместите оператор test в комментарий и сохраните его с результатами. В противном случае поместите это в комментарий в коде с результатами.
источник
Временная таблица злоупотреблений.
Именно такие вещи:
Не создавайте временную таблицу из запроса, только для удаления ненужных строк.
И да, я видел страницы кода в этой форме в производственных БД.
источник
Противоположный взгляд: чрезмерная одержимость нормализацией.
Большинство систем SQL / RBDB предоставляют множество функций (транзакции, репликация), которые весьма полезны даже для ненормализованных данных. Дисковое пространство дешево, и иногда может быть проще (более простой код, более быстрое время разработки) манипулировать / фильтровать / искать извлеченные данные, чем написать схему 1NF и справиться со всеми возникающими в ней трудностями (сложные объединения, неприятные подвыборы). , и т.д).
Я обнаружил, что чрезмерно нормализованные системы часто преждевременно оптимизируются, особенно на ранних стадиях разработки.
(больше мыслей об этом ... http://writeonly.wordpress.com/2008/12/05/simple-object-db-using-json-and-python-sqlite/ )
источник
Я просто собрал это, основываясь на некоторых ответах SQL здесь, на SO.
Серьезным антипаттерном является думать, что триггеры относятся к базам данных, а обработчики событий - к ООП. Существует мнение, что в триггеры может быть включена любая старая логика, которая срабатывает, когда транзакция (событие) происходит в таблице.
Не правда. Одно из больших отличий состоит в том, что триггеры синхронны - с удвоенной силой, потому что они синхронны в операции набора, а не в операции строки. Со стороны ООП события с точностью до наоборот - эффективный способ реализации асинхронных транзакций.
источник
Хранимые процедуры или функции без каких-либо комментариев ...
источник
1) Я не знаю, что это «официальный» анти-шаблон, но мне не нравится и стараюсь избегать строковых литералов как магических значений в столбце базы данных.
Пример из таблицы MediaWiki 'image':
(Я просто замечаю другой корпус, еще одну вещь, чтобы избежать)
Я разрабатываю такие случаи, как поиск int в таблицах ImageMediaType и ImageMajorMime с первичными ключами int.
2) преобразование даты / строки, основанное на определенных настройках NLS
без идентификатора формата
источник
Идентичные подзапросы в запросе.
источник
Измененное представление - представление, которое изменяется слишком часто и без уведомления или причины. Изменение будет замечено в самое неподходящее время или, что еще хуже, будет ошибочным и никогда не будет замечено. Возможно, ваше приложение сломается, потому что кто-то придумал более подходящее название для этого столбца. Как правило, представления должны расширять полезность базовых таблиц при сохранении договора с потребителями. Исправляйте проблемы, но не добавляйте функции или не изменяйте поведение, для этого создайте новый вид. Для смягчения не делитесь представлениями с другими проектами и используйте CTE, когда платформы позволяют. Если в вашем магазине есть администратор базы данных, вы, вероятно, не сможете изменить представления, но в этом случае все ваши представления будут устаревшими и бесполезными.
Параметр! - может ли запрос иметь более одной цели? Возможно, но следующий человек, который читает это, не узнает до глубокой медитации. Даже если они вам сейчас не нужны, скорее всего, вы это сделаете, даже если это «просто» для отладки. Добавление параметров сокращает время обслуживания и делает вещи СУХИМЫМИ. Если у вас есть предложение where, у вас должны быть параметры.
Дело без дела -
источник
Два, которые я нахожу больше всего, и могут иметь значительные затраты с точки зрения производительности:
Использование курсоров вместо выражения на основе набора. Я предполагаю, что это происходит часто, когда программист думает правильно.
Использование коррелированных подзапросов, когда объединение с производной таблицей может выполнить эту работу.
источник
Помещение вещей во временные таблицы, особенно люди, которые переходят с SQL Server на Oracle, имеют привычку чрезмерно использовать временные таблицы. Просто используйте вложенные операторы select.
источник
Разработчики, которые пишут запросы, не имея представления о том, что делает приложения SQL (как отдельные запросы, так и многопользовательские системы) быстрыми или медленными. Это включает в себя незнание о:
источник
Использование SQL в качестве прославленного пакета ISAM (Indexed Sequential Access Method). В частности, вложенные курсоры вместо объединения операторов SQL в один, хотя и больший, оператор. Это также считается «злоупотреблением оптимизатором», поскольку на самом деле оптимизатор мало что может сделать. Это может быть объединено с неподготовленными заявлениями для максимальной неэффективности:
Правильное решение (почти всегда) - объединить два оператора SELECT в один:
Единственное преимущество версии с двойным циклом состоит в том, что вы можете легко определить разрывы между значениями в таблице 1, поскольку внутренний цикл заканчивается. Это может быть фактором в отчетах о нарушениях управления.
Кроме того, сортировка в приложении, как правило, нет-нет.
источник
Использование первичных ключей в качестве суррогата для адресов записей и использование внешних ключей в качестве суррогата для указателей, встроенных в записи.
источник