Почему Oracle varchar2 имеет обязательный размер в качестве параметра определения? - PullRequest
15 голосов
/ 11 февраля 2010

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

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

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

То же самое для определения типа VARCHAR2(10) или VARCHAR2(1000).

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

Ответы [ 6 ]

24 голосов
/ 11 февраля 2010

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

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

7 голосов
/ 11 февраля 2010

Я думаю, что важно помнить исторический контекст, в котором были созданы реляционные базы данных. В то время, когда они разрабатывались (в конце 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, и поскольку я не собираюсь начинать писать свою собственную реляционную базу данных (у меня есть свои собственные ветряные мельницы, на которые можно наклониться, спасибо :-) Я просто согласен со статус-кво.

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

5 голосов
/ 11 февраля 2010

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

А если серьезно:

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

3 голосов
/ 11 февраля 2010

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

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

3 голосов
/ 11 февраля 2010

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

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

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

0 голосов
/ 18 января 2016

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

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

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

...