全量比较-pg侧前置内容

1. 创建测试表SQL

-- PostgreSQL 完整数据类型测试表
-- 用于测试跨数据库整行 hash 一致性

DROP TABLE IF EXISTS test_all_types CASCADE;

CREATE TABLE test_all_types (
    -- ============ 主键与索引 ============
                                id BIGSERIAL PRIMARY KEY,
                                unique_key VARCHAR(100) UNIQUE,

    -- ============ 数值类型 ============
                                col_smallint SMALLINT,
                                col_integer INTEGER,
                                col_bigint BIGINT,
                                col_decimal DECIMAL(20, 10),
                                col_numeric NUMERIC(30, 15),
                                col_real REAL,
                                col_double DOUBLE PRECISION,
                                col_smallserial_col SMALLSERIAL,
                                col_serial_col SERIAL,

    -- ============ 货币类型 ============
                                col_money MONEY,

    -- ============ 字符类型 ============
                                col_varchar VARCHAR(50),
                                col_varchar_empty VARCHAR(10),
                                col_char CHAR(10),
                                col_char_padded CHAR(20),
                                col_text TEXT,
                                col_text_long TEXT,

    -- ============ 二进制类型 ============
                                col_bytea BYTEA,

    -- ============ 日期时间类型 ============
                                col_date DATE,
                                col_time_without_zone TIME,
                                col_time_without_zone_3 TIME(3),
                                col_time_without_zone_6 TIME(6),
                                col_time_with_zone TIME WITH TIME ZONE,
                                col_time_with_zone_3 TIME(3) WITH TIME ZONE,
                                col_timestamp_without TIMESTAMP,
                                col_timestamp_3 TIMESTAMP(3),
                                col_timestamp_6 TIMESTAMP(6),
                                col_timestamp_with_zone TIMESTAMP WITH TIME ZONE,
                                col_timestamp_with_zone_3 TIMESTAMP(3) WITH TIME ZONE,
                                col_timestamp_with_zone_6 TIMESTAMP(6) WITH TIME ZONE,
                                col_interval interval,

    -- ============ 布尔类型 ============
                                col_boolean BOOLEAN,

    -- ============ 位串类型 ============
                                col_bit_varying BIT VARYING(20),
                                col_bit BIT(8),

    -- ============ 网络类型 ============
                                col_cidr CIDR,
                                col_inet INET,
                                col_macaddr MACADDR,

    -- ============ UUID ============
                                col_uuid UUID,

    -- ============ JSON 类型 ============
                                col_json JSON,
                                col_jsonb JSONB,

    -- ============ 数组类型 ============
                                col_int_array INTEGER[],
                                col_text_array TEXT[],
                                col_varchar_array VARCHAR(50)[],

    -- ============ 几何类型 ============
                                col_point POINT,
                                col_line LINE,
                                col_lseg LSEG,
                                col_box BOX,
                                col_path PATH,
                                col_polygon POLYGON,
                                col_circle CIRCLE,

    -- ============ 范围类型 ============
                                col_int4range INT4RANGE,
                                col_int8range INT8RANGE,
                                col_numrange NUMRANGE,
                                col_tsrange TSRANGE,
                                col_tstzrange TSTZRANGE,
                                col_daterange DATERANGE,

    -- ============ XML ============
                                col_xml XML,

    -- ============ 全文搜索 ============
                                col_tsvector TSVECTOR,

    -- ============ 允许 NULL 的列 ============
                                col_null_integer INTEGER,
                                col_null_varchar VARCHAR,
                                col_null_date DATE
);

CREATE INDEX idx_unique_key ON test_all_types(unique_key);
CREATE INDEX idx_timestamp ON test_all_types(col_timestamp_with_zone);
CREATE INDEX idx_varchar ON test_all_types(col_varchar);
CREATE INDEX idx_integer ON test_all_types(col_integer);
CREATE INDEX idx_tsvector_idx ON test_all_types USING GIN (col_tsvector);

COMMENT ON TABLE test_all_types IS 'PostgreSQL 全数据类型测试表 - 用于跨数据库整行 hash 一致性验证';

-- ============ 插入测试数据 ============
TRUNCATE TABLE test_all_types RESTART IDENTITY;

INSERT INTO test_all_types (
    unique_key,
    col_smallint, col_integer, col_bigint,
    col_decimal, col_numeric, col_real, col_double,
    col_smallserial_col, col_serial_col,
    col_money,
    col_varchar, col_varchar_empty, col_char, col_char_padded,
    col_text, col_text_long,
    col_bytea,
    col_date,
    col_time_without_zone, col_time_without_zone_3, col_time_without_zone_6,
    col_time_with_zone, col_time_with_zone_3,
    col_timestamp_without, col_timestamp_3, col_timestamp_6,
    col_timestamp_with_zone, col_timestamp_with_zone_3, col_timestamp_with_zone_6,
    col_interval,
    col_boolean,
    col_bit_varying, col_bit,
    col_cidr, col_inet, col_macaddr,
    col_uuid,
    col_json, col_jsonb,
    col_int_array, col_text_array, col_varchar_array,
    col_point, col_line, col_lseg, col_box, col_path, col_polygon, col_circle,
    col_int4range, col_int8range, col_numrange,
    col_tsrange, col_tstzrange, col_daterange,
    col_xml,
    col_tsvector,
    col_null_integer, col_null_varchar, col_null_date
) VALUES (
             -- ============ 第一条:常规值 + 边界值 ============
             'ROW_001_BASIC',
             -32768, 0, 9223372036854775807,
             1234567890.1234567890::DECIMAL(20, 10),
             -999999999999.999999999999999::NUMERIC(30, 15),
             3.1415927::REAL, 3.141592653589793::DOUBLE PRECISION,
             DEFAULT, DEFAULT,
             '$1,234.56'::MONEY,
             'Hello World', '', 'A', '文本填充测试' || LPAD('', 13, ' '),
             '这是很长的 TEXT 内容,
             可以包含多行文本。
             支持任意长度的字符串。',
             REPEAT('A', 1000),
             E'\\xDEADBEEF'::BYTEA,
             '2024-12-31'::DATE,
             '13:45:59'::TIME, '13:45:59.123'::TIME(3), '13:45:59.123456'::TIME(6),
             '13:45:59+08:00'::TIME WITH TIME ZONE, '13:45:59.123+08:00'::TIME(3) WITH TIME ZONE,
             '2024-01-01 00:00:00'::TIMESTAMP,
             '2024-06-15 12:30:45.123'::TIMESTAMP(3),
             '2024-06-15 12:30:45.123456'::TIMESTAMP(6),
             '2024-06-15 20:30:45+08:00'::TIMESTAMP WITH TIME ZONE,
             '2024-06-15 20:30:45.123+08:00'::TIMESTAMP(3) WITH TIME ZONE,
             '2024-06-15 20:30:45.123456+08:00'::TIMESTAMP(6) WITH TIME ZONE,
             '2 years 3 months 15 days 6 hours 30 minutes 45 seconds'::INTERVAL,
             true,
             B'10101', B'11110000',
             '192.168.0.0/24'::CIDR, '10.0.0.1'::INET, '08:00:2b:01:02:03'::MACADDR,
             'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::UUID,
             '{"name": "张三", "age": 30, "score": 95.5, "active": true, "tags": ["测试", "示例"], "nested": {"key": "value"}}'::JSON,
             '{"name": "李四", "age": 25, "items": [1, 2, 3], "float": 3.14159}'::JSONB,
             ARRAY[1, 2, 3, 4, 5],
             ARRAY['apple', 'banana', '中文水果'],
             ARRAY['high', 'medium', 'low']::VARCHAR(50)[],
             POINT(10.5, 20.5), LINE '{1, 2, 3}', LSEG '[(0,0), (10,10)]',
             BOX '(5,5), (0,0)', PATH '[(0,0), (1,1), (2,0)]',
             POLYGON '((0,0), (1,0), (1,1), (0,1))', CIRCLE '<(5,5), 3>',
             INT4RANGE '[1, 100]', INT8RANGE '[1000, 9999999999999]',
             NUMRANGE '[0.1, 100.5]',
             TSRANGE '[2024-01-01 00:00:00, 2024-12-31 23:59:59]',
             TSTZRANGE '[2024-01-01 00:00:00+08:00, 2024-12-31 23:59:59+08:00]',
             DATERANGE '[2024-01-01, 2024-12-31]',
             '<root><item id="1">第一个元素</item><item id="2">第二个元素</item></root>'::XML,
             to_tsvector('english', 'The quick brown fox jumps over the lazy dog 中文全文搜索测试'),
             NULL, NULL, NULL
         ),

-- ============ 第二条:边界值 + NULL + 极值 ============
         (
             'ROW_002_EDGE_CASES',
             32767, -2147483648, -9223372036854775808,
             -0.0000000001::DECIMAL(20, 10), 0.000000000000001::NUMERIC(30, 15),
             -0.0::REAL, -1.7976931348623157E+308::DOUBLE PRECISION,
             DEFAULT, DEFAULT,
             '$ -1,000.00'::MONEY,
             'Unicode: 中文 日本語 한국어', '   ', '中', LPAD('', 20, 'X'),
             '', E'\t\n\r\\\'\"',
             E'\\x00010203040506070809'::BYTEA,
             '1970-01-01'::DATE,
             '00:00:00'::TIME, '00:00:00.000'::TIME(3), '00:00:00.000000'::TIME(6),
             '00:00:00+00:00'::TIME WITH TIME ZONE, '23:59:59.999+00:00'::TIME(3) WITH TIME ZONE,
             '1970-01-01 00:00:00'::TIMESTAMP,
             '1970-01-01 00:00:00.000'::TIMESTAMP(3),
             '1970-01-01 00:00:00.000000'::TIMESTAMP(6),
             '1970-01-01 00:00:00+00:00'::TIMESTAMP WITH TIME ZONE,
             '2038-01-19 03:14:07.999+00:00'::TIMESTAMP(3) WITH TIME ZONE,
             '2038-01-19 03:14:07.999999+00:00'::TIMESTAMP(6) WITH TIME ZONE,
             '-1 year -2 months -3 days'::INTERVAL,
             false,
             B'00000', B'00000000',
             '2001:db8::/32'::CIDR, '::1'::INET, '00:00:00:00:00:00'::MACADDR,
             '00000000-0000-0000-0000-000000000000'::UUID,
             'null'::JSON, '[]'::JSONB,
             ARRAY[]::INTEGER[], ARRAY[]::TEXT[], ARRAY[NULL]::VARCHAR(50)[],
             POINT(0, 0), NULL, NULL, NULL, NULL, NULL, NULL,
             INT4RANGE '[0, 0]', NULL, NULL, NULL, NULL, NULL,
             NULL,
             to_tsvector('english', ''),
             NULL, NULL, NULL
         ),

-- ============ 第三条:全值填充 + BC 日期 + 最大 UUID ============
         (
             'ROW_003_FULL_VALUES',
             1, 1, 1,
             1.0::DECIMAL(20, 10), 1.0::NUMERIC(30, 15),
             1.0::REAL, 1.0::DOUBLE PRECISION,
             DEFAULT, DEFAULT,
             '$0.01'::MONEY,
             '1', '1', '1', '1                   ',
             '1', '1',
             E'\\x01'::BYTEA,
             '0001-01-01 BC'::DATE,
             '00:00:00'::TIME, '00:00:00.001'::TIME(3), '00:00:00.000001'::TIME(6),
             '00:00:00+00:00'::TIME WITH TIME ZONE, '00:00:00.001+00:00'::TIME(3) WITH TIME ZONE,
             '0001-01-01 00:00:00 BC'::TIMESTAMP,
             '0001-01-01 00:00:00.001 BC'::TIMESTAMP(3),
             '0001-01-01 00:00:00.000001 BC'::TIMESTAMP(6),
             '0001-01-01 00:00:00+00:00 BC'::TIMESTAMP WITH TIME ZONE,
             '0001-01-01 00:00:00.001+00:00 BC'::TIMESTAMP(3) WITH TIME ZONE,
             '0001-01-01 00:00:00.000001+00:00 BC'::TIMESTAMP(6) WITH TIME ZONE,
             '1 second'::INTERVAL,
             NULL,
             B'1', B'00000001',
             '0.0.0.0/0'::CIDR, '0.0.0.0'::INET, 'ff:ff:ff:ff:ff:ff'::MACADDR,
             'ffffffff-ffff-ffff-ffff-ffffffffffff'::UUID,
             '0'::JSON, '0'::JSONB,
             ARRAY[0], ARRAY['0'], ARRAY['0']::VARCHAR(50)[],
             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
             INT4RANGE '[0, 1)', NULL, NULL, NULL, NULL, NULL,
             '<element/>'::XML,
             to_tsvector('simple', 'test'),
             100, '有值的 VARCHAR', '2024-01-01'
         );

SELECT '数据插入完成' AS status;
SELECT COUNT(*) AS total_rows FROM test_all_types;
SELECT id, unique_key, col_varchar, col_integer, col_boolean FROM test_all_types;

2.hash查询语句

SELECT 
    id,
    md5(
        COALESCE(col_smallint::text, '') ||
        COALESCE(col_integer::text, '') ||
        COALESCE(col_bigint::text, '') ||
        COALESCE(ROUND(col_decimal::numeric, 10)::text, '') ||
        COALESCE(ROUND(col_numeric::numeric, 15)::text, '') ||
        COALESCE(ROUND(col_real::numeric, 7)::text, '') ||
        COALESCE(ROUND(col_double::numeric, 15)::text, '') ||
        COALESCE(col_money::text, '') ||
        COALESCE(col_varchar, '') ||
        COALESCE(col_text, '') ||
        COALESCE(TRIM(col_char)::text, '') ||
        COALESCE(encode(col_bytea, 'hex'), '') ||
        COALESCE(col_boolean::text, '') ||
        COALESCE(col_uuid::text, '') ||
        COALESCE((col_timestamp_with_zone AT TIME ZONE 'UTC')::text, '') ||
        COALESCE(col_jsonb::text, '') ||
        COALESCE(array_to_string(col_int_array, ','), '') ||
        COALESCE(col_int4range::text, '')
    ) AS row_hash
FROM test_all_types
ORDER BY id;

3.pgsql查询字段名称和数据类型(忽略精度)

SELECT 
    table_schema,
    column_name,
    data_type
FROM 
    information_schema.columns
WHERE 
    table_schema = 'test' AND
    table_name = 'test_all_types'
ORDER BY 
    table_schema, ordinal_position;

4.pgsql查询字段名称和数据类型(不忽略精度)(查询结果需要注意区分,例如时间戳)

SELECT 
    a.attname AS 字段名,
    format_type(a.atttypid, a.atttypmod) AS 完整类型
FROM 
    pg_attribute a
WHERE 
    a.attrelid = 'test.test_all_types'::regclass
    AND a.attnum > 0
    AND NOT a.attisdropped
ORDER BY 
    a.attnum;

5.gaussDB查询字段名称和数据类型(未验证)

-- 基础查询
SELECT 
    column_name,
    data_type
FROM 
    information_schema.columns
WHERE 
    table_schema = 'public'  -- 或具体 schema 名
    AND table_name = 'test_all_types'
ORDER BY 
    ordinal_position;
    
-- 带精度信息的完整类型查询
SELECT 
    column_name AS 字段名,
    CASE 
        WHEN data_type IN ('character varying', 'character') 
            THEN data_type || '(' || character_maximum_length || ')'
        WHEN data_type = 'numeric' 
            THEN data_type || '(' || numeric_precision || ',' || numeric_scale || ')'
        WHEN data_type IN ('timestamp without time zone', 'timestamp with time zone') 
            THEN data_type || COALESCE('(' || datetime_precision || ')', '')
        ELSE data_type
    END AS 完整类型
FROM 
    information_schema.columns
WHERE 
    table_schema = 'public'
    AND table_name = 'test_all_types'
ORDER BY 
    ordinal_position;
    
-- 使用 GaussDB 系统表查询
SELECT 
    a.attname AS 字段名,
    format_type(a.atttypid, a.atttypmod) AS 数据类型
FROM 
    pg_attribute a
WHERE 
    a.attrelid = 'public.test_all_types'::regclass
    AND a.attnum > 0
    AND NOT a.attisdropped
ORDER BY 
    a.attnum;

6.gaussDB生成整行hash(未验证)

-- 在 GaussDB 中生成 hash 记录
CREATE TABLE hash_records AS
SELECT 
    id,
    unique_key,
    md5(
        COALESCE(col_smallint::text, '') ||
        COALESCE(col_integer::text, '') ||
        COALESCE(col_bigint::text, '') ||
        COALESCE(col_decimal::text, '') ||
        COALESCE(col_numeric::text, '') ||
        COALESCE(col_real::text, '') ||
        COALESCE(col_double::text, '') ||
        COALESCE(col_money::text, '') ||
        COALESCE(col_varchar, '') ||
        COALESCE(col_varchar_empty, '') ||
        COALESCE(TRIM(col_char)::text, '') ||
        COALESCE(col_text, '') ||
        COALESCE(encode(col_bytea, 'hex'), '') ||
        COALESCE(col_date::text, '') ||
        COALESCE(col_time_without_zone::text, '') ||
        COALESCE(col_time_without_zone_3::text, '') ||
        COALESCE(col_time_without_zone_6::text, '') ||
        COALESCE(col_time_with_zone::text, '') ||
        COALESCE(col_time_with_zone_3::text, '') ||
        COALESCE(col_timestamp_without::text, '') ||
        COALESCE(col_timestamp_3::text, '') ||
        COALESCE(col_timestamp_6::text, '') ||
        COALESCE(col_timestamp_with_zone::text, '') ||
        COALESCE(col_timestamp_with_zone_3::text, '') ||
        COALESCE(col_timestamp_with_zone_6::text, '') ||
        COALESCE(col_interval::text, '') ||
        COALESCE(col_boolean::text, '') ||
        COALESCE(col_bit_varying::text, '') ||
        COALESCE(col_bit::text, '') ||
        COALESCE(col_cidr::text, '') ||
        COALESCE(col_inet::text, '') ||
        COALESCE(col_macaddr::text, '') ||
        COALESCE(col_uuid::text, '') ||
        COALESCE(col_json::text, '') ||
        COALESCE(col_jsonb::text, '') ||
        COALESCE(array_to_string(col_int_array, ','), '') ||
        COALESCE(array_to_string(col_text_array, ','), '') ||
        COALESCE(array_to_string(col_varchar_array, ','), '') ||
        COALESCE(col_point::text, '') ||
        COALESCE(col_line::text, '') ||
        COALESCE(col_lseg::text, '') ||
        COALESCE(col_box::text, '') ||
        COALESCE(col_path::text, '') ||
        COALESCE(col_polygon::text, '') ||
        COALESCE(col_circle::text, '') ||
        COALESCE(col_int4range::text, '') ||
        COALESCE(col_int8range::text, '') ||
        COALESCE(col_numrange::text, '') ||
        COALESCE(col_tsrange::text, '') ||
        COALESCE(col_tstzrange::text, '') ||
        COALESCE(col_daterange::text, '') ||
        COALESCE(col_xml::text, '') ||
        COALESCE(col_tsvector::text, '') ||
        COALESCE(col_null_integer::text, '') ||
        COALESCE(col_null_varchar, '') ||
        COALESCE(col_null_date::text, '')
    ) AS gaussdb_hash
FROM test_all_types;

SELECT * FROM hash_records;

 

posted @ 2026-05-12 20:04  景之1231  阅读(3)  评论(0)    收藏  举报