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

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

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

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

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

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

6 ответов


Это то же самое, чтобы определить тип 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>

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

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


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

цифры разные. Для начала максимальный размер числа намного меньше текстового эквивалента (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> 

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


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

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

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

SUBTYPE MY_STRING IS VARCHAR2(4000);

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

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

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


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

но, серьезно:

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


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

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

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


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

или купить очень большие конверты.


возможно влияние производительности: в MySQL,temporary tables и MEMORY tables магазине VARCHAR столбец как столбец фиксированной длины, проложенный к ее максимальной длине.

если вы дизайн VARCHAR столбцы намного больше, чем самый большой размер, который вам нужен, вы будете потреблять больше памяти, чем вам нужно. Это влияет cache efficiency, sorting speed, etc.

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