Подтвердить что ты не робот

Oracle не имеет битового типа данных для столбцов таблицы

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

Oracle не поддерживает бит-тип данных - или, что-то еще, что имеет очевидный смысл в сценариях true/false. Однако, несмотря на то, что до того, как я присоединился к команде, мои предки решили вместо этого использовать поля char (1), используя специальную букву для обозначения yes/true. К сожалению, наше приложение используется людьми во всем мире, и по причинам, которые откровенно бросают вызов всем моим попыткам понять, используемая ценность варьируется в зависимости от локализации.

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

Я заметил, что эта практика, похоже, продвигается вперед в новое развитие, которое кажется мне безумным, поэтому я думаю о том, чтобы вместо этого предлагать Number (1,0) - 0 считаться ложным/нет, что-то иначе интерпретируется как true/yes...

Простой вопрос - может ли кто-нибудь подумать о причине, что это может быть плохая идея?

Пока мы об этом знаем, кто-нибудь знает, почему Oracle не поддерживает простой булевский тип? Разве это не опечатка?

Приветствия в ожидании,

Martin.

4b9b3361

Ответ 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%.

Ответ 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