Не используйте нестандартные типы данных
Обоснование
В стандартном SQL более чем достаточно типов данных, чтобы описать практически любые сущности реального мира. Нестандартные же типы данных зачастую несовместимы не только с другими продуктами, но и с другими версиями того же продукта.
Например, в семействе SQL Server/Sybase имеется тип данных MONEY. Он позволяет при отображении добавлять к числам разделители и обозначения валют, а также применять правила расчетов, отличные от правил для типов NUMERIC или DECIMAL Это означает, что в интерфейсе нужно разбираться с тем, правильно ли обработались разделители и символы валют, а также проверять правильность вычислений. Зачем вставлять в DDL нечто такое, что потом в интерфейсе придется переделывать?
В языке высокого уровня, наподобие SQL, нет места и таким машинно-зависимым типам как BIT или BYTE. Язык SQL определяется вне зависимости от физической реализации. Этот базовый принцип моделирования информации называется абстрагированием данных (data abstraction).
Биты и байты позволяют вам подобраться максимально близко к физическому представлению данных. Какого типа компьютер вы используете? Какова длина слова на нем — 8, 16, 32, 64 или 128 битов? Применяется дополнение до единицы или дополнение до двух? Как обстоит дело со значением NULL? Оно должно быть у любого типа данных, в том числе и у BIT. Но бит равен либо 0, либо 1 — третьего (NULL) не дано! Как реализованы биты в хост-языке? Знаете ли вы, что использование значений +1, +0, -0 и -1 для булевой алгебры далеко от согласованности? Это относится ко всем хост-языкам— существующим, разрабатываемым и еще непридуманным. Очевидно, что даже хороший программист не сможет написать переносимый код, опустившись до такого низкого уровня, как работа с индивидуальными битами. Уж если стандарты разрешают работать с десятичными числами, биты нам вообще не нужны!
На практике возможны две ситуации. Биты могут применяться в качестве индивидуальных атрибутов или в качестве вектора, представляющего некий объединенный признак. Используя бит в качестве индивидуального атрибута, вы ограничиваете его двумя значениями, которые могут быть несовместимы с хост-языком или с другими реализациями SQL, неочевидны конечному пользователю и не допускают расширения.
Векторный битовый атрибут, состоящий из цепочки значений “да/нет”, является признаком программиста, все еще мыслящего в терминах языков программирования второго и третьего поколений. Представьте себе шесть компонентов решения о предоставлении банковского займа, представленные в виде битовой модели мира второго поколения. У вас имеется 64 возможных вектора, но смысл имеют только 5 из них (нельзя, например, одновременно быть банкротом и иметь хорошую кредитную историю). Чтобы сохранить целостность данных, вы можете принять два решения.
1. Проигнорировать проблему. На самом деле, большинство новичков так и поступает. Когда база данных превращается в ералаш без какой бы то ни было целостности, они переходят ко второму решению.
2. Создать сложные ограничения СНЕСК() с использованием пользовательских или нестандартных библиотечных функций для работы с битами, которые заставляют забыть о переносимости кода и замедляют его работу до черепашьей скорости.
Теперь попробуем добавить к вектору седьмое условие. С какого конца его добавить? Можно ли быть уверенными, что программа после добавления будет работать на всех мыслимых аппаратных платформах? Сумеете ли вы отследить все места, где код обращается к битовому атрибуту по его позиции в векторе?
Приходится порядком посидеть и подумать над представлением данных высокого уровня, которое было бы достаточно общим для расширения, абстрагирования и переносимости. Должно ли представление решения о займе быть иерархическим, составным, векторным? Нужно ли предусмотреть коды для неизвестных, отсутствующих или неприменимых параметров? Разрабатывать подобные вещи непросто!
Исключения
В настоящее время оправдать применение нестандартных и машинно-зависимых типов данных могут лишь совершенно особенные обстоятельства. За 20 лет консультирования по SQL-программированию мне ни разу не встречались ситуации, в которых нельзя было бы обойтись стандартным типом данных или оператором CREATE DOMAIN.
Даже если такая ситуация встретится вам, проверьте, нельзя ли заменить нестандартный тип данных пользовательским типом. Если вам приходится работать с чем-то экзотическим, наподобие звуков, изображений, документов, подумайте, стоит ли вообще выполнять эту работу в SQL. Возможно, правильнее будет прибегнуть к более специализированному ПО.