Изменить varchar в тип boolean в PostgreSQL
я начал работать над проектом, где есть довольно большая таблица (около 82,000,000 строк), которая, я думаю, очень раздута. Одно из полей определяется как:
consistency character varying NOT NULL DEFAULT 'Y'::character varying
он используется как логическое значение, значения всегда должны быть ('Y' | 'N').
Примечание: нет ограничения check и т. д.
Я пытаюсь придумать причины, чтобы оправдать изменение этого поля. Вот что у меня есть:
- он используется как логическое, так это то. Явное лучше, чем неявное.
- это защитит от ошибок кодирования, потому что прямо сейчас там все, что может быть преобразовано в текст, будет идти вслепую.
вот мой вопрос(ы).
- как насчет размера / хранения? БД-UTF-8. Итак, Я думаю там действительно не так много накоплений в этой области. Это должно быть 1 байт для
boolean
, но также 1 байт для'Y'
в UTF-8 (по крайней мере, это то, что я получить, когда я проверяю длину в Python). Есть ли здесь какие-либо другие накладные расходы на хранение, которые будут сохранены? - производительность запроса? И Postgres будет вам прирост производительности, где причиной "
=TRUE
" и "='Y'
"?
2 ответов
PostgreSQL (в отличие от Oracle) имеет полноценный boolean
тип. Как правило, флаг "да/нет" должен быть boolean
. Это правильный тип для использования!
как насчет размера / хранения?
в основном, a boolean
колонки занимает 1 байт на диске
в то время как text
или character varying
(цитируя руководство ЗДЕСЬ) ...
требование к хранению для короткой строки (до 126 байт) это 1 байт плюс фактическая строка
это 2 байт для простого персонажа. Таким образом, вы можете сократить хранение колонки пополам.
фактическое хранение сложнее, чем это. Есть некоторые фиксированные накладные расходы на таблицу,страница и строка есть NULL
для хранения и некоторые типы требуют выравнивание данных. Общее влияние будет очень ограничено - если заметно на все.
подробнее о том, как измерить реальное пространство.
кодирование UTF8
здесь нет никакой разницы. Основные ASCII-символы совместимы с другими кодировками, такими как LATIN-1
.
в вашем случае, согласно вашему описанию, вы должны сохранить не нулевое ограничение у вас уже есть-независимо от базового типа.
производительность запроса?
будет немного лучше случае с булевскими. Помимо того, что немного меньше, логика для boolean
это проще и varchar
или text
также, как правило, обременен сортировка конкретные правила. Но не ждите многого от чего-то столь простого.
вместо
WHERE consistency = 'Y'
вы могли бы написать:
WHERE consistency = TRUE
но, действительно, Вы можете упростить просто:
WHERE consistency
дополнительная оценка не требуется.
изменить тип
преобразование таблицы просто:
ALTER TABLE tbl ALTER consistency TYPE boolean
USING CASE consistency WHEN 'Y' THEN TRUE ELSE FALSE END;
этой CASE
выражение складывает все, что не TRUE
('Y') to FALSE
. Ограничение NOT NULL просто остается.
ни размер хранилища, ни производительность запроса не будут значительно лучше переключаться с одного VARCHAR на логическое значение. Хотя вы правы, что технически чище использовать boolean, когда вы говорите о двоичном значении, стоимость изменения, вероятно, значительно выше, чем выгода. Если вы беспокоитесь о правильности, вы можете поставить проверку на столбец, например
ALTER TABLE tablename ADD CONSTRAINT consistency CHECK (consistency IN ('Y', 'N'));