01008 implicit zero bit padding ๋?
PostgreSQL ์๋ฌ ์ฝ๋ 01008์ WARNING: implicit zero bit padding ๊ฒฝ๊ณ ๋ก, ๋นํธ ๋ฌธ์์ด(bit string) ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฐ ๋ ์ง์ ๋ ๊ธธ์ด๋ณด๋ค ์งง์ ๊ฐ์ด ์
๋ ฅ๋ ๊ฒฝ์ฐ PostgreSQL์ด ์๋์ผ๋ก ์ฐ์ธก์ 0๋นํธ๋ฅผ ์ฑ์ ๋ฃ๋ ์ํฉ์์ ๋ฐ์ํฉ๋๋ค. ์ด๋ ์๋ฐํ ๋งํด ์น๋ช
์ ์ธ ์๋ฌ๊ฐ ์๋ ๊ฒฝ๊ณ (WARNING) ์์ค์ ์๋ฆผ์ด์ง๋ง, ๋ฐ์ดํฐ ์ ํฉ์ฑ ์ธก๋ฉด์์ ์๋์น ์์ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ ์ ์์ด ์ค๋ฌด์์ ๋ฐ๋์ ์ฃผ์ํด์ผ ํฉ๋๋ค. ํนํ BIT(n) ํ์
์ ์ปฌ๋ผ์ ๊ธธ์ด๊ฐ ๋ง์ง ์๋ ๋นํธ ๋ฆฌํฐ๋ด์ ์ฝ์
ํ๊ฑฐ๋ ์บ์คํ
ํ ๋ ์ฃผ๋ก ๋ํ๋๋ฉฐ, ๋ฐ์ดํฐ๊ฐ ๋ฌต์์ ์ผ๋ก ๋ณํ๋์๋ค๋ ์ฌ์ค์ ๊ฐ๋ฐ์๊ฐ ์ธ์งํ์ง ๋ชปํ๋ฉด ์ถํ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๊ฐ ์์๊ณผ ๋ฌ๋ผ์ง๋ ๋ฒ๊ทธ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
์ฃผ์ ๋ฐ์ ์์ธ
1. BIT(n) ์ปฌ๋ผ์ ๊ธธ์ด๊ฐ ์งง์ ๋นํธ ๋ฆฌํฐ๋ด ์ง์ ์ฝ์
BIT(n) ํ์
์ ์ ํํ n๋นํธ์ ๊ณ ์ ๊ธธ์ด๋ฅผ ์๊ตฌํฉ๋๋ค. ์๋ฅผ ๋ค์ด BIT(8) ์ปฌ๋ผ์ B'101'์ฒ๋ผ 3๋นํธ์ง๋ฆฌ ๊ฐ์ ๊ทธ๋๋ก ์ฝ์
ํ๋ฉด, PostgreSQL์ ๊ฒฝ๊ณ ๋ฅผ ๋ฐ์์ํค๋ฉด์ ๋๋จธ์ง 5์๋ฆฌ๋ฅผ 0์ผ๋ก ์๋ ํจ๋ฉํ์ฌ 10100000์ผ๋ก ์ ์ฅํฉ๋๋ค. ์ด ๋์์ SQL ํ์ค์ ๋ฐ๋ฅธ ๊ฒ์ด์ง๋ง, ๊ฐ๋ฐ์๊ฐ ์ฐ์ธก ํจ๋ฉ์ ์ธ์งํ์ง ๋ชปํ ์ฑ ๋นํธ ์ฐ์ฐ์ ์ํํ๋ฉด ์ ํ ๋ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ ๋์ถ๋ ์ ์์ต๋๋ค.
2. ์บ์คํ (CAST) ๋๋ ํ ๋ณํ ์ ๋นํธ ๊ธธ์ด ๋ถ์ผ์น
VARCHAR ๋๋ TEXT ํ์
์ผ๋ก ์ ์ฅ๋ ๋นํธ ํจํด ๋ฌธ์์ด์ BIT(n) ํ์
์ผ๋ก CASTํ ๋, ์๋ณธ ๋ฌธ์์ด์ ๊ธธ์ด๊ฐ n๋ณด๋ค ์งง์ผ๋ฉด ๋์ผํ ์ ๋ก ํจ๋ฉ ๊ฒฝ๊ณ ๊ฐ ๋ฐ์ํฉ๋๋ค. ํนํ ETL ์์
์ด๋ ๋ฐ์ดํฐ ๋ง์ด๊ทธ๋ ์ด์
๊ณผ์ ์์ ์์ค ์์คํ
์ ๋นํธ ํํ ๋ฐฉ์์ด ์ผ์ ํ์ง ์์ ๊ฒฝ์ฐ ์ด ๋ฌธ์ ๊ฐ ๋น๋ฒํ๊ฒ ๋ํ๋ฉ๋๋ค. ์ผ๊ด ์ฒ๋ฆฌ ์ฟผ๋ฆฌ์์ ์์ฒ ๊ฑด์ ๊ฒฝ๊ณ ๊ฐ ๋ก๊ทธ๋ฅผ ๊ฐ๋ ์ฑ์ฐ๋ ์ฌํ๊ฐ ๋ฐ์ํ๊ธฐ๋ ํฉ๋๋ค.
3. ํจ์๋ ์ฐ์ฐ ๊ฒฐ๊ณผ๋ฅผ BIT(n) ์ปฌ๋ผ์ ์ ์ฅํ ๋ ๊ธธ์ด ๋ฏธ๊ฒ์ฆ
๋นํธ ์ฐ์ฐ(&, |, #, ~) ๋๋ substring() ํจ์ ๋ฑ์ ์ฌ์ฉํด ๋นํธ ๊ฐ์ ์กฐ์ํ ๊ฒฐ๊ณผ๋ฅผ ๊ณ ์ ๊ธธ์ด BIT(n) ์ปฌ๋ผ์ ์ ์ฅํ ๋, ๊ฒฐ๊ณผ ๋นํธ์ด์ ๊ธธ์ด๊ฐ ์ปฌ๋ผ ์ ์๋ณด๋ค ์งง์ผ๋ฉด ์ญ์ ํจ๋ฉ์ด ๋ฐ์ํฉ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์
๋ ์ด์ด์์ ๋์ ์ผ๋ก ๋นํธ ๋ง์คํฌ๋ฅผ ์์ฑํ๋ ๋ก์ง์ด ์๋ ๊ฒฝ์ฐ, ๊ฒฝ์ฐ์ ๋ฐ๋ผ ๊ธธ์ด๊ฐ ๊ฐ๋ณ์ ์ผ ์ ์์ด ์ด ์์ธ์ด ๋์ฑ ์ํํฉ๋๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ
์์ธ 1 ํด๊ฒฐ: ์ฝ์ ์ ๋นํธ ๋ฆฌํฐ๋ด ๊ธธ์ด๋ฅผ ๋ช ์์ ์ผ๋ก ๋ง์ถ๊ธฐ
๋นํธ ๋ฆฌํฐ๋ด์ ์ฝ์
ํ๊ธฐ ์ ์ ํญ์ ์ปฌ๋ผ์ n ๊ฐ์ ๋ง๊ฒ ํจ๋ฉ์ ์ง์ ์ํํ์ฌ PostgreSQL์ด ๋ฌต์์ ์ผ๋ก ์ฒ๋ฆฌํ์ง ์๋๋ก ํฉ๋๋ค.
-- ๋ฌธ์ ๊ฐ ๋๋ ์ฟผ๋ฆฌ (BIT(8) ์ปฌ๋ผ์ 3๋นํธ ์ฝ์
โ ๊ฒฝ๊ณ ๋ฐ์)
CREATE TABLE bit_test (
id SERIAL PRIMARY KEY,
flags BIT(8) NOT NULL
);
-- ๊ฒฝ๊ณ ๋ฐ์: implicit zero bit padding
INSERT INTO bit_test (flags) VALUES (B'101');
-- ํด๊ฒฐ์ฑ
1: ๊ธธ์ด๋ฅผ ์ ํํ ๋ง์ถฐ ์ฝ์
INSERT INTO bit_test (flags) VALUES (B'10100000');
-- ํด๊ฒฐ์ฑ
2: lpad ํจ์๋ฅผ ํ์ฉํด ๋์ ์ผ๋ก ์ฐ์ธก ํจ๋ฉ ์ฒ๋ฆฌ
-- (๋ฌธ์์ด ๊ธฐ๋ฐ์ผ๋ก ๋นํธ๋ฅผ ๋ง๋ค ๋ ์ ์ฉ)
INSERT INTO bit_test (flags)
SELECT (rpad(bit_str, 8, '0'))::BIT(8)
FROM (VALUES ('101')) AS t(bit_str);
-- ๊ฒฐ๊ณผ ํ์ธ
SELECT id, flags, flags::TEXT AS flags_text
FROM bit_test;
์์ธ 2 ํด๊ฒฐ: ๋ช ์์ CAST ์ ์ ๊ธธ์ด ๋ณด์ ํจ์ ์ ์ฉ
ETL ๋๋ ๋ง์ด๊ทธ๋ ์ด์
์ฟผ๋ฆฌ์์ ์์ค ๋ฐ์ดํฐ์ ๋นํธ ๋ฌธ์์ด ๊ธธ์ด๋ฅผ ๋ฏธ๋ฆฌ ์ ๊ทํํ ๋ค ์บ์คํ
ํฉ๋๋ค.
-- ๋ฌธ์ ์ํฉ: ๋ค์ํ ๊ธธ์ด์ ๋นํธ ๋ฌธ์์ด์ด ์์ธ ์คํ
์ด์ง ํ
์ด๋ธ
CREATE TABLE staging_bits (
raw_bits TEXT
);
INSERT INTO staging_bits (raw_bits)
VALUES ('1'), ('1010'), ('110011'), ('10101010');
-- ๊ฒฝ๊ณ ๋ฐ์ํ๋ ๋ฐฉ์ (๊ธธ์ด ๋ถ์ผ์น ์บ์คํ
)
SELECT raw_bits::BIT(8) FROM staging_bits;
-- ํด๊ฒฐ์ฑ
: rpad๋ก 8์๋ฆฌ๋ก ์ ๊ทํํ ํ ์บ์คํ
SELECT
raw_bits,
rpad(raw_bits, 8, '0')::BIT(8) AS normalized_bits
FROM staging_bits;
-- ๊ธธ์ด ๊ฒ์ฆ ๋ก์ง ํฌํจ ๋ฒ์ (๊ธธ์ด ์ด๊ณผ ๋ฐ์ดํฐ๋ ๋ฐฉ์ด)
SELECT
raw_bits,
CASE
WHEN length(raw_bits) > 8
THEN left(raw_bits, 8)::BIT(8) -- ์ด๊ณผ๋ถ ์ ์ญ
WHEN length(raw_bits) < 8
THEN rpad(raw_bits, 8, '0')::BIT(8) -- ๋ถ์กฑ๋ถ ํจ๋ฉ
ELSE
raw_bits::BIT(8) -- ์ ํํ 8์๋ฆฌ
END AS safe_bits
FROM staging_bits;
์์ธ 3 ํด๊ฒฐ: ๋นํธ ์ฐ์ฐ ๊ฒฐ๊ณผ์ ๊ธธ์ด๋ฅผ ๋ช ์์ ์ผ๋ก ๊ฒ์ฆ ํ ์ ์ฅ
์ฐ์ฐ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๊ธฐ ์ ์ bit_length() ํจ์๋ก ๊ธธ์ด๋ฅผ ํ์ธํ๊ณ , ํ์ํ๋ค๋ฉด ๋ช
์์ ์ผ๋ก ํจ๋ฉํฉ๋๋ค.
-- ๋นํธ ์ฐ์ฐ ๊ฒฐ๊ณผ ๊ธธ์ด ํ์ธ
SELECT
B'10100000' & B'11110000' AS and_result,
bit_length(B'10100000' & B'11110000') AS result_length;
-- substring์ผ๋ก ๋นํธ๋ฅผ ์๋ฅธ ๋ค ์ ์ฅ ์ ๊ธธ์ด ๋ถ์ผ์น ๋ฐฉ์ง
-- substring ๊ฒฐ๊ณผ๊ฐ 8๋นํธ๋ณด๋ค ์งง์ ์ ์์ผ๋ฏ๋ก ํจ๋ฉ ๋ช
์
WITH computed AS (
SELECT substring(B'10110001' FROM 1 FOR 5) AS partial_bits
)
INSERT INTO bit_test (flags)
SELECT
CASE
WHEN bit_length(partial_bits) < 8
THEN (partial_bits::TEXT || repeat('0', 8 - bit_length(partial_bits)))::BIT(8)
ELSE partial_bits::BIT(8)
END
FROM computed;
-- ์ ์ฅ๋ ๋ฐ์ดํฐ ํ์ธ
SELECT id, flags, flags::TEXT, bit_length(flags) AS len
FROM bit_test
ORDER BY id;
์๋ฐฉ ๋ฐฉ๋ฒ
1. BIT(n) ์ปฌ๋ผ ์ฝ์ /์์ ์ CHECK ์ ์ฝ ์กฐ๊ฑด ๋๋ ํธ๋ฆฌ๊ฑฐ๋ก ๊ธธ์ด ๊ฐ์ ๊ฒ์ฆ
์ ํ๋ฆฌ์ผ์ด์
์ฝ๋๊ฐ ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ ๋ฒจ์์ ๋นํธ ๊ธธ์ด๋ฅผ ๊ฐ์ ํ๋ฉด, ์๋ชป๋ ๊ธธ์ด์ ๋ฐ์ดํฐ๊ฐ ๋ฌต์์ ํจ๋ฉ ์์ด ๋ค์ด์ค๋ ๊ฒ์ ์์ฒ ์ฐจ๋จํ ์ ์์ต๋๋ค. client_min_messages ์ค์ ์ WARNING ์ด์์ผ๋ก ์ ์งํ์ฌ ๊ฒฝ๊ณ ๋ก๊ทธ๋ฅผ ํญ์ ๋ชจ๋ํฐ๋งํ๋ ์ต๊ด๋ ์ค์ํฉ๋๋ค.
-- CHECK ์ ์ฝ ์กฐ๊ฑด์ผ๋ก ์ ํํ ๋นํธ ๊ธธ์ด ๊ฐ์
ALTER TABLE bit_test
ADD CONSTRAINT chk_flags_length
CHECK (bit_length(flags) = 8);
-- ๋๋ ํ
์ด๋ธ ์์ฑ ์๋ถํฐ ์ ์ฉ
CREATE TABLE bit_strict (
id SERIAL PRIMARY KEY,
flags BIT(8) NOT NULL,
CONSTRAINT chk_exact_length CHECK (bit_length(flags) = 8)
);
-- ๋ก๊ทธ ๋ ๋ฒจ ์ค์ ํ์ธ (postgresql.conf ๋๋ ์ธ์
๋ ๋ฒจ)
SET client_min_messages = 'WARNING';
SHOW client_min_messages;
2. ๋นํธ ์ฒ๋ฆฌ ๋ก์ง์ ์ ๋ดํ๋ ๋ํผ ํจ์(Wrapper Function) ์์ฑ ๋ฐ ๊ณต์
ํ ์ ์ฒด๊ฐ ๋นํธ ์ฝ์
/๋ณํ ์ ๋์ผํ ์์ ๋ก์ง์ ์ฌ์ฉํ๋๋ก ๊ณต์ฉ ํจ์๋ฅผ ๋ง๋ค์ด ์คํค๋ง์ ๋ฐฐํฌํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๊ฐ๋ฐ์๊ฐ ์ง์ ์บ์คํ
ํ๋ ๋์ ๊ฒ์ฆ์ด ๋ด์ฅ๋ ํจ์๋ฅผ ํธ์ถํ๊ฒ ๋์ด, ์ค์๋ก ๋ฐ์ํ๋ ๋ฌต์์ ํจ๋ฉ ๊ฒฝ๊ณ ๋ฅผ ๊ตฌ์กฐ์ ์ผ๋ก ์๋ฐฉํ ์ ์์ต๋๋ค.
-- ์์ ํ ๋นํธ ๋ณํ ๋ํผ ํจ์
CREATE OR REPLACE FUNCTION safe_to_bit(
p_bit_str TEXT,
p_length INT
)
RETURNS BIT
LANGUAGE plpgsql
AS $$
DECLARE
v_padded TEXT;
BEGIN
IF length(p_bit_str) > p_length THEN
RAISE EXCEPTION '๋นํธ ๋ฌธ์์ด ๊ธธ์ด(%)๊ฐ ์ง์ ๊ธธ์ด(%)๋ฅผ ์ด๊ณผํฉ๋๋ค.',
length(p_bit_str), p_length;
ELSIF length(p_bit_str) < p_length THEN
v_padded := rpad(p_bit_str, p_length, '0');
RAISE NOTICE '๋นํธ ํจ๋ฉ ์ ์ฉ: % โ %', p_bit_str, v_padded;
ELSE
v_padded := p_bit_str;
END IF;
RETURN v_padded::BIT(64); -- ์ต๋ 64๋นํธ ์ง์ ์์
END;
$$;
-- ์ฌ์ฉ ์์
SELECT safe_to_bit('101', 8); -- NOTICE ๋ฐ์ + 10100000 ๋ฐํ
SELECT safe_to_bit('10101010', 8); -- ์ ์ ์ฒ๋ฆฌ
๊ด๋ จ ์๋ฌ
-
22026(string_data_length_mismatch):BIT VARYING(n)๋๋CHAR(n)๋ฑ ๊ธธ์ด ์ ํ์ด ์๋ ํ์ ์์ ์ ๋ ฅ๊ฐ์ด ์ ์ธ๋ ๊ธธ์ด๋ฅผ ์ด๊ณผํ ๋ ๋ฐ์ํ๋ ์๋ฌ๋ก,01008์ ๋ฐ๋ ๋ฐฉํฅ ๋ฌธ์ ๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค. -
22000(data_exception): ๋นํธ ์ฐ์ฐ ์ ํผ์ฐ์ฐ์์ ๊ธธ์ด๊ฐ ์๋ก ๋ง์ง ์์ ๋ ๋ฐ์ํ๋ ์ผ๋ฐ ๋ฐ์ดํฐ ์์ธ๋ก, ๋นํธ ํ์ ์์ ์01008๊ณผ ํจ๊ป ์์ฃผ ๋ง์ฃผ์น๊ฒ ๋ฉ๋๋ค. -
01000(warning): PostgreSQL ๊ฒฝ๊ณ ์ ์ผ๋ฐ ์์ ์นดํ ๊ณ ๋ฆฌ ์ฝ๋๋ก,01008์ ์ด ์นดํ ๊ณ ๋ฆฌ์ ์ํ๋ฉฐclient_min_messages์ค์ ์ ๋ฐ๋ผ ํด๋ผ์ด์ธํธ ์ถ๋ ฅ ์ฌ๋ถ๊ฐ ๊ฒฐ์ ๋ฉ๋๋ค.










