Почему Oracle varchar2 имеет обязательный размер как параметр определения?

Я хочу знать, почему Oracle нужен параметр размера в определении VARCHAR2.

Я думаю, что это для ограничения. Это был бы более оптимальный вариант, как который оракул выбирает этот параметр как дополнительное NUMBER тип данных?

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

Это - то же для определения типа VARCHAR2(10) или VARCHAR2(1000).

Я предполагаю, это - ненужное ограничение. В противном случае Вы знаете о реальном случае, когда это ограничение привело к чему-то полезному? И почему никакое такое объявление в NUMBER ввести?

15
задан APC 3 January 2014 в 05:06
поделиться

5 ответов

То же самое, чтобы определить тип varchar2 (10) или varchar2 (1000).

Нет, это совсем не одно и то же.

  1. Длина столбца - полезные метаданные для разработчиков, создающих экраны.
  2. Аналогичным образом инструменты автоматического запроса, такие как TOAD и SQL Developer, используют длину столбца при отображении результатов.
  3. База данных использует длину переменной при выделении памяти для коллекций PL / SQL. Поскольку эта память выходит из PGA, чрезмерное увеличение объявления переменной может привести к сбою программ из-за нехватки памяти на сервере.
  4. Есть аналогичные проблемы с объявлением одиночных переменных в программах PL / SQL, просто коллекции имеют тенденцию умножать проблему.
  5. Столбцы большого размера создают проблемы для составных индексов. Следующее относится к базе данных с блоками 8K

....

SQL> create table t23 (col1 varchar2(4000), col2 varchar2(4000))
  2  /

Table created.

SQL> create index t23_i on t23(col1,col2)
  2  /
create index t23_i on t23(col1,col2)
                      *
ERROR at line 1:
ORA-01450: maximum key length (6398) exceeded


SQL>

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

Это правда, что изменение размера столбца, когда оказывается, что мы недооценили, может быть утомительным. Но это случается не очень часто, и мы можем облегчить большую часть боли, используя объявления% TYPE и SUBTYPE в нашем PL / SQL вместо жестко заданных значений переменной длины.


"Почему нет такого объявления в типе NUMBER"

Цифры разные.Для начала, максимальный размер числа намного меньше текстового эквивалента (38 цифр гарантированной точности).

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

SQL> select vsize(123456789012345678901) n1
  2         , vsize(999999999999999999999999999999) n2
  3         , vsize(0.000000000000000000001) n3
  4         , vsize(1000000000000000000000000) n4
  5  from dual
  6  /

        N1         N2         N3         N4
---------- ---------- ---------- ----------
        12         16          2          2

SQL> 

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

24
ответ дан 1 December 2019 в 00:49
поделиться

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

  • Память распределение на считывателях данных (на основе максимального размера строки)
  • Индексирование большого столбца влияет на размер блоков
  • И т. д.

Я уверен, что есть и другие причины, о которых может подумать кто-то еще, но те, которые я видел в прошлом проекте, где кто-то выбрал varchar2 (4000) все.

3
ответ дан 1 December 2019 в 00:49
поделиться

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

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

        DependencyObject dep = (DependencyObject)e.OriginalSource;
        while ((dep != null) && !(dep is ListBoxItem))
        {
            dep = VisualTreeHelper.GetParent(dep);
        }

        if (dep != null)
        {
            // TODO: do stuff with the item here.
        }
-121--2060630-

Вы ищете

voters.TakeWhile(p => {
   bool exceeded = voicesSoFar > voicesNeeded ;
   voicesSoFar += p.Voices;
   return !exceeded;
});

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

voters.TakeWhile(p => (voicesSoFar += p.Voices) - p.Voices < voicesNeeded);
-121--1711489-

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

Или купить ОЧЕНЬ большие конверты.

3
ответ дан 1 December 2019 в 00:49
поделиться

Я думаю, что важно помнить исторический контекст, в котором были разработаны реляционные базы данных. В то время, когда они разрабатывались (конец 70-х - начало 80-х годов) общедоступные компьютеры были намного меньше (в плане памяти и дискового пространства) и менее мощными (в плане процессора), чем сейчас, и управление этими ресурсами было неизбежной проблемой. COBOL был обычным языком бизнес-вычислений (и до сих пор широко используется), а объектно-ориентированные языки, такие как Smalltalk и C++, были неизвестны, для всех практических целей. В то время ожидалось, что программы будут точно объявлять, сколько памяти им потребуется для каждого элемента данных, например, 10 байт для строки, 2 байта для короткого целого числа, 4 байта для числа с плавающей запятой и т.д., и поэтому такой стиль объявления использовался только что разработанными реляционными базами данных. Более того, было сделано предположение, что каждый элемент данных будет объявлять (неявно или явно) объем памяти, который ему требуется, и это было заложено в реляционные движки на очень фундаментальном уровне.

Сейчас, со временем, это требование несколько смягчилось, по крайней мере, в том, что касается хранения данных на диске. Я полагаю, что в Oracle тип данных NUMBER будет гибко распределять пространство так, что будет использоваться только минимальный объем пространства, необходимый для хранения его значения, и что столбцы VARCHAR2 будут использовать достаточно места на диске для хранения фактических данных, не сохраняя пробелы, хотя вам все еще нужно объявлять максимальный объем памяти, требуемый для VARCHAR2.

Вы можете взглянуть на пакет SYS.STANDARD, чтобы получить представление о том, как объявлять подтипы VARCHAR2. Например, если вам нужен собственный тип 'string', который можно использовать без спецификации длины, вы можете попробовать:

SUBTYPE MY_STRING IS VARCHAR2(4000);

Однако, будьте осторожны с этим, если вы собираетесь индексировать рассматриваемый столбец (как указал @APC).

Я согласен, что лучше было бы просто объявить STRING (который, кстати, определен в SYS.STANDARD как подтип VARCHAR2) без необходимости объявлять длину, но Oracle работает не так, и поскольку я не собираюсь начинать писать свою собственную реляционную базу данных (у меня есть свои ветряные мельницы, на которые я могу накрениться, спасибо :-), я просто соглашусь со статус-кво.

Надеюсь, это поможет.

7
ответ дан 1 December 2019 в 00:49
поделиться

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

Но серьезно:

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

5
ответ дан 1 December 2019 в 00:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: