Oracle не имеет битового типа данных для столбцов таблицы
Я работаю разработчиком в небольшой команде разработчиков, и что-то раздражало меня до такой степени, что я решил действовать...
Oracle не поддерживает бит-тип данных - или, что-то еще, что имеет очевидный смысл в сценариях true/false. Однако, несмотря на то, что до того, как я присоединился к команде, мои предки решили вместо этого использовать поля char (1), используя специальную букву для обозначения yes/true. К сожалению, наше приложение используется людьми во всем мире, и по причинам, которые откровенно бросают вызов всем моим попыткам понять, используемая ценность варьируется в зависимости от локализации.
Да, я знаю, что совершенно ненужно для значений в фоновом контенте, которые пользователь никогда не видит - однако...
Я заметил, что эта практика, похоже, продвигается вперед в новое развитие, которое кажется мне безумным, поэтому я думаю о том, чтобы вместо этого предлагать Number (1,0) - 0 считаться ложным/нет, что-то иначе интерпретируется как true/yes...
Простой вопрос - может ли кто-нибудь подумать о причине, что это может быть плохая идея?
Пока мы об этом знаем, кто-нибудь знает, почему Oracle не поддерживает простой булевский тип? Разве это не опечатка?
Приветствия в ожидании,
Martin.
Ответы
Ответ 1
Я предпочитаю char (1) по числу (1), так как с некоторым разумным выбором символов очевидно, какой символ имеет то, что имеет логическое значение.
Конечно, вы должны бороться со всеми различными вариациями, выбирать один и обеспечивать его использование, помещая контрольные ограничения в столбцы.
Хотя, вероятно, в конце вашего случая, генерация схемы из другого инструмента часто заботится хотя бы о проблеме согласованности. Я лично предпочитаю спящий режим для этой цели, но это очень специфическая ситуация.
И, конечно, это вопиющее предзнаменование. Чтобы сделать это хуже, PL/SQL имеет логическое значение, но вы не можете использовать его в операторах SQL.
Ответ 2
Используйте CHAR (1) и ограничение, чтобы разрешать только "1" и "0".
...
col CHAR(1),
CONSTRAINT cons_atable_col1 CHECK (col1 IN ('1','0'))
Ответ 3
Я не владею английским языком, поэтому я предпочитаю использовать 1 или 0 или 1 и 0. Использование "Y" и "N" имеет мало смысла, если вы не кодируете на английском языке (да, кодировка на родном языке существует). Использование "SI" и "NO" или "S" и "N" не выглядит профессиональным (точно так же, как именование переменных с акцентированными буквами). Напротив, ноты и ноль довольно стандартизированы, если вы закодированы в C, PHP или JavaScript. В любом случае, я всегда добавляю соответствующее ограничение, чтобы запретить любой другой символ. Помимо субъективных проблем, я не думаю, что есть заметное увеличение производительности при выборе CHAR или NUMBER. Мне нравятся цифры немного больше, потому что мне не нужно их цитировать:)
Я согласен с этим вопиющим упущением, но я читал серьезно горячие дискуссии по этому вопросу на некоторых форумах Oracle; это своего рода религиозная проблема. Некоторые утверждают, что булевы относятся к типам данных приложения и не имеют места в ядре базы данных. Честно говоря, я считаю, что это один из тех, с кем мы были так долго без этого, что мы лучше говорили, что это было в отношении вещей.
Кстати, у MySQL есть тип BOOLEAN, но это синоним TINYINT (1), поэтому он в конечном итоге равен 1 и 0; что хорошо, потому что он также имеет константы TRUE и FALSE, которые оценивают 1 и 0.
Ответ 4
Ниже приведено обсуждение Ask Tom. Дает ориентированный на Oracle взгляд на проблему.
Как и для хранения, char (1) на самом деле немного (без каламбура) более эффективно:
SQL> CREATE TABLE xx (c CHAR(1), n NUMBER);
Table created
SQL> insert into xx values('T', 1);
1 row inserted
SQL> select dump(c), dump(n) from xx;
DUMP(C) DUMP(N)
------------------- -------------
Typ=96 Len=1: 84 Typ=2 Len=2: 193,2
Ответ 5
Число (1) не лучше char (1). Особенно, если это будет в дополнение к существующему char (1). Это просто добавит к путанице.
FWIW, Oracle во внутренних представлениях (например, USER_TAB_COLUMNS) использует varchar2 (3) (YES и NO). Не уверен, что они здесь на 100%.
Ответ 6
В соответствии с этим руководством Oracle вы должны использовать NUMBER (3). Сумасшедший, но правда.
http://docs.oracle.com/cd/B19306_01/gateways.102/b14270/apa.htm
Ответ 7
Вопрос старен, но до тех пор, пока не будет использована последняя версия оракула, все еще остается верным вопросом.
Я бы решил проблему таким образом:
Создайте таблицу, которая содержит возможные значения для текста true/false плюс локализованного отображения f.e.
T $KEYWORDS
ITEMNO ITEMTEXT ITEMTEXT_DE ITEMTEXT_FE...
0 False Falsch
1 True Wahr
Вместо True/False это может быть также выбрано, не выбрано и т.д.
И затем добавьте ключ foreigh к вашему столбцу в эту таблицу. Таким образом, у вас есть только допустимые значения, и они не меняются с локализацией.
Другое хорошее решение imho использует ограничение проверки в столбце данных. Это не работает, если ваши значения могут отличаться в одной и той же базе данных/столбце в зависимости от локализации клиентов.
alter table tblLocations add flag number CONSTRAINT <constraintname> CHECK (flag IN (1,0));
Ответ 8
Oracle использует "биты" (а не тип данных как таковой) в разных представлениях словаря данных.
Например, представление dba_users имеет:
..
, DECODE (BITAND (u.spare1, 128), 128, 'YES', 'NO')
..
, DECODE (BITAND (u.spare1, 256), 256, 'Y', 'N')
..
который показывает способ обхода этого в некотором роде. Если вам не нужно часто изменять "логические" биты, вы можете использовать тот же подход, что и Oracle с Oracle 6 (по крайней мере). Создайте таблицу с столбцом NUMBER и VIEW поверх нее, которая скрывает сложность операций BITAND.
пс. На стороне примечания, Oracle JDBC имеет "бит" тип данных https://docs.oracle.com/cd/E16338_01/appdev.112/e13995/oracle/jdbc/OracleTypes.html#BIT, а также вы уже знаете, что PL/SQL имеет Boolean. Хотя это, вероятно, вам не поможет. См. Подход BITAND выше, если он соответствует вашему делу.
Ответ 9
https://docs.oracle.com/cd/E17952_01/refman-5.5-en/char.html
![введите описание изображения здесь]()
Как сказал DCookie, char (1) более эффективен.
Поскольку VARCHAR2 (VARCHAR) пуст, содержит 1 байт, но когда мы сохраняем 1 символ, тогда пустой размер 1 байта + с размером символа 1 байт → 2 байта, необходимо сохранить 1 символ в varchar