У меня вопрос по поводу ALTER TABLE
команды для действительно большой таблицы (почти 30 миллионов строк). Один из столбцов - это a, varchar(255)
и я хотел бы изменить его размер на a varchar(40)
. По сути, я хотел бы изменить свой столбец, выполнив следующую команду:
ALTER TABLE mytable ALTER COLUMN mycolumn TYPE varchar(40);
У меня нет проблем, если процесс очень длинный, но кажется, что моя таблица больше не читается во время команды ALTER TABLE. Есть ли умнее? Может быть, добавить новый столбец, скопировать значения из старого столбца, удалить старый столбец и, наконец, переименовать новый?
Любая подсказка будет с благодарностью! Заранее спасибо,
Примечание: я использую PostgreSQL 9.0.
postgresql
varchar
alter-table
Labynocle
источник
источник
resizing
не заставит столик занимать меньше места?varchar(255)
PostgreSQL, то он не будет выделять 255 байтов для значения, реальная длина которого составляет 40 байтов. Он выделит 40 байтов (плюс некоторые внутренние издержки). Единственное, чтоbe changed by the
ALTER TABLE`, - это максимальное количество байтов, которое вы можете сохранить в этом столбце, не получая ошибки от PG.Ответы:
Описание того, как это сделать, приведено в разделе Изменение размера столбца в таблице PostgreSQL без изменения данных . Вы должны взломать данные каталога базы данных. Единственный способ сделать это официально - с помощью ALTER TABLE, и, как вы заметили, изменение заблокирует и перезапишет всю таблицу во время ее работы.
Обязательно ознакомьтесь с разделом « Типы символов » в документации, прежде чем изменять это. Всевозможные странные случаи, о которых нужно знать здесь. Проверка длины выполняется, когда значения сохраняются в строках. Если вы взломаете нижний предел, это вообще не уменьшит размер существующих значений. Было бы целесообразно выполнить сканирование всей таблицы в поисках строк, длина поля которых превышает 40 символов после внесения изменений. Вам нужно будет выяснить, как их урезать вручную - чтобы вы вернули некоторые блокировки только для слишком больших - потому что если кто-то попытается обновить что-либо в этом ряду, он отклонит его как слишком большое сейчас, в тот момент, когда это идет, чтобы сохранить новую версию ряда. Веселье наступает для пользователя.
VARCHAR - это ужасный тип, который существует в PostgreSQL только для соответствия связанной с ним ужасной части стандарта SQL. Если вас не волнует совместимость с несколькими базами данных, рассмотрите возможность хранения ваших данных в формате TEXT и добавьте ограничение, ограничивающее их длину. Ограничения, которые вы можете изменить без этой проблемы блокировки / перезаписи таблицы, и они могут выполнять больше проверки целостности, чем просто проверка слабой длины.
источник
В PostgreSQL 9.1 есть более простой способ
http://www.postgresql.org/message-id/162867790801110710g3c686010qcdd852e721e7a559@mail.gmail.com
источник
Хорошо, я, наверное, опаздываю на вечеринку, НО ...
НЕ НУЖНО ИЗМЕНИТЬ КОЛОННУ В ВАШЕМ ДЕЛЕ!
Postgres, в отличие от некоторых других баз данных, достаточно умен, чтобы использовать только достаточно места для размещения строки (даже используя сжатие для более длинных строк), поэтому даже если ваш столбец объявлен как VARCHAR (255) - если вы храните строки из 40 символов в столбец, использование пространства будет 40 байтов + 1 байт служебных данных.
( http://www.postgresql.org/docs/9.0/interactive/datatype-character.html )
Спецификация размера в VARCHAR используется только для проверки размера вставляемых значений, она не влияет на структуру диска. Фактически, поля VARCHAR и TEXT хранятся в Postgres одинаково .
источник
Я столкнулся с той же проблемой, пытаясь обрезать VARCHAR с 32 до 8 и получить
ERROR: value too long for type character varying(8)
. Я хочу оставаться как можно ближе к SQL, потому что я использую самодельную JPA-подобную структуру, которую нам, возможно, придется переключаться на разные СУБД в соответствии с выбором клиента (PostgreSQL является стандартной). Следовательно, я не хочу использовать хитрость изменения системных таблиц.Я закончил, используя
USING
утверждение вALTER TABLE
:Как отметил @raylu,
ALTER
получает эксклюзивную блокировку таблицы, поэтому все другие операции будут отложены до его завершения.источник
ALTER
приобретает исключительную блокировку на столе и предотвращает все остальные операцииДобавление нового столбца и замена нового на старый работал для меня, на redshift postgresql, обратитесь к этой ссылке для более подробной информации https://gist.github.com/mmasashi/7107430
источник
Вот кеш страницы, описанной Грегом Смитом. В случае, если это также умирает, оператор alter выглядит так:
Если ваша таблица - TABLE1, столбец - COL1, и вы хотите установить для него 35 символов (+4 требуется для унаследованных целей в соответствии со ссылкой, возможно, это служебная информация, указанная AH в комментариях).
источник
если вы введете alter в транзакцию, таблица не должна быть заблокирована:
это сработало у меня быстро, несколько секунд на столе с более чем 400 000 строк.
источник
ALTER
оператора? Это не так.COMMIT
. Оболочка имеет смысл, только если вы хотите поместить больше команд в одну транзакцию.Я нашел очень простой способ изменить размер, то есть аннотацию @Size (min = 1, max = 50), которая является частью «import javax.validation.constraints», то есть «import javax.validation.constraints.Size;»
источник
Попробуйте запустить следующую таблицу alter:
источник