Почему Oracle varchar2 имеет обязательный размер в качестве параметра определения?
Я хочу знать, зачем Oracle нужен параметр размера в определении VARCHAR2
,
Я думаю, что для ограничения. Было бы лучше, если бы oracle воспринимал этот параметр как необязательный NUMBER
тип данных?
У меня часто возникают проблемы с изменением размеров старых таблиц до больших размеров, потому что иногда значение больше, чем определение размера VARCHAR2
колонка.
Это то же самое, чтобы определить тип VARCHAR2(10
) или же VARCHAR2(1000)
,
Я думаю, это ненужное ограничение. Если нет, знаете ли вы реальный случай, когда это ограничение привело к чему-то полезному? И почему нет такой декларации в NUMBER
тип?
6 ответов
Это то же самое, что определить тип varchar2(10) или varchar2(1000).
Нет, это совсем не одно и то же.
- Длина столбца - это полезные метаданные для разработчиков, создающих экраны.
- Аналогично, автоматические инструменты запросов, такие как TOAD и SQL Developer, используют длину столбца при отображении результатов.
- База данных использует длину переменной при выделении памяти для коллекций PL/SQL. Поскольку эта память выходит из PGA, увеличение размера объявления переменной может привести к сбою программ, поскольку серверу не хватило памяти.
- Есть аналогичные проблемы с объявлением отдельных переменных в программах на PL/SQL, просто коллекции имеют тенденцию к увеличению проблемы.
- Большие столбцы создают проблемы для составных индексов. Следующее находится в базе данных с блоками 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>
Тем не менее, остается хорошей практикой указывать масштаб и точность везде, где это возможно, особенно когда мы имеем дело с целыми числами, скажем, или деньгами.
Я думаю, что важно помнить исторический контекст, в котором были созданы реляционные базы данных. В то время, когда они разрабатывались (в конце 70-х - начале 80-х), общедоступные компьютеры были намного меньше (с точки зрения памяти и дискового пространства) и менее мощными (с точки зрения процессора), чем мы сейчас, и управление этими ресурсами было обязательно непреодолимая забота. COBOL был распространенным языком бизнес-вычислений (и до сих пор широко используется), а объектно-ориентированные языки, такие как Smalltalk и C++, были неизвестны для всех практических целей. В то время ожидалось, что программы будут точно указывать, сколько памяти им потребуется для каждого элемента данных, например, 10 байтов для строки, 2 байта для короткого целого числа, 4 байта для числа с плавающей запятой и т. Д., И поэтому этот стиль объявления был использован недавно разработанными реляционными базами данных. Более того, было сделано предположение, что каждый элемент данных будет объявлять (неявно или явно) объем требуемой памяти, и это было закодировано в реляционных механизмах на очень фундаментальном уровне.
Теперь со временем это требование несколько смягчилось, по крайней мере, в том, что касается хранения данных на диске. Я считаю, что в Oracle тип данных NUMBER будет гибко распределять пространство, так что фактически будет использоваться только минимальный объем пространства, необходимый для хранения его значения, и что столбцы VARCHAR2 будут использовать только дисковое пространство для хранения фактических данных без сохранения конечных пробелов, хотя вам все равно нужно объявить максимальный объем памяти, необходимый для VARCHAR2.
Вы можете взглянуть на пакет SYS.STANDARD, чтобы понять, как объявлять подтипы VARCHAR2. Например, если вы хотите свой собственный тип 'string', который вы можете использовать без привязки к спецификации длины, вы можете попробовать:
SUBTYPE MY_STRING IS VARCHAR2(4000);
Однако, будьте осторожны с этим, если вы собираетесь индексировать рассматриваемый столбец (как указывалось ранее @APC).
Я согласен, что я предпочел бы просто иметь возможность объявить STRING (то есть BTW, определенный в SYS.STANDARD как подтип VARCHAR2) без необходимости объявлять длину, но это не совсем так, как работает Oracle, и как я Я не собираюсь начинать писать свою собственную реляционную базу данных (у меня есть свои собственные ветряные мельницы, на которые можно наклониться, спасибо:-) Я просто согласен со статус-кво.
Надеюсь, это поможет.
Почему бы не иметь каждый столбец в каждой таблице базы данных CLOB? Таким образом, вам не нужно беспокоиться о максимальной длине...
Но серьезно:
Ограничения длины типа данных существуют по той же причине, что и любые ограничения: они уменьшают количество проверок на ошибки, которые необходимо выполнить для разбрасывания всего кода вашего приложения, гарантируя, что любые данные, успешно сохраненные в таблице, соответствуют определенным вами ограничениям.
Несмотря на то, что он не выделяет установленное количество байтов на диске, как это делает поле char, все же есть веские причины для определения размера:
- Распределение памяти на считыватели данных (в зависимости от максимального размера строки)
- Индексирование большого столбца вводит размеры блоков в игру
- Так далее...
Я уверен, что есть и другие причины, о которых кто-то может подумать, но это те, которые я видел в прошлом проекте, где кто-то решил varchar2(4000)
все.
С точки зрения извлечения информации очень полезно знать, насколько велико поле. Например, если вам нужно напечатать адрес на конверте или вывести его на экран, вы хотите знать, насколько большим должно быть поле.
Или купить ОЧЕНЬ большие конверты.
Возможное влияние на производительность: в MySQL temporary tables
а также MEMORY tables
хранить VARCHAR
столбец как столбец фиксированной длины, дополняемый до максимальной длины.
Если вы разрабатываете VARCHAR
Если столбцы намного больше нужного вам размера, вы будете использовать больше памяти, чем нужно. Это влияет cache efficiency, sorting speed, etc
,
Таким образом, вы даете максимальную длину, которая находится под вашей строкой. например, если у вас максимальная длина символа 10, поэтому не указывайте его длину 100 или более.