Vấn đề ClickHouse: Cập nhật cột có kiểu dữ liệu Nullable(Int32) luôn trả về giá trị cố định 93147008

Tình huống gặp phải

Khi thực hiện cập nhật dữ liệu trong ClickHouse, việc cập nhật các cột có kiểu Nullable(Int32) bất kể giá trị mới được cung cấp là gì, kết quả cuối cùng luôn là một giá trị cố định: 93147008.

Các bước tái tạo

1. Tạo bảng kiểm thử

CREATE TABLE product_inventory_test
(
    `product_id` Int32,
    `category_id` Nullable(String),
    `stock_level` Nullable(Int32),
    `is_active` Int32,
    `min_stock` Int32,
    `max_stock` Nullable(Int32),
    `reorder_point` Nullable(Int32),
    `last_updated` Nullable(DateTime),
    `alert_flag` Nullable(Int32)
)
ENGINE = MergeTree
ORDER BY product_id
SETTINGS index_granularity = 8192;

2. Chèn dữ liệu mẫu

INSERT INTO product_inventory_test(product_id, category_id, stock_level, is_active, min_stock, max_stock, reorder_point, last_updated, alert_flag) VALUES (101, 'A1', 50, 1, 10, 100, 20, '2023-10-27 10:00:00', 0);
INSERT INTO product_inventory_test(product_id, category_id, stock_level, is_active, min_stock, max_stock, reorder_point, last_updated, alert_flag) VALUES (102, 'A2', 75, 1, 15, 150, 30, '2023-10-27 10:05:00', 0);
INSERT INTO product_inventory_test(product_id, category_id, stock_level, is_active, min_stock, max_stock, reorder_point, last_updated, alert_flag) VALUES (103, 'B1', 30, 1, 5, 50, 10, '2023-10-27 10:10:00', 0);
INSERT INTO product_inventory_test(product_id, category_id, stock_level, is_active, min_stock, max_stock, reorder_point, last_updated, alert_flag) VALUES (104, 'B2', 90, 1, 20, 200, 40, '2023-10-27 10:15:00', 0);
INSERT INTO product_inventory_test(product_id, category_id, stock_level, is_active, min_stock, max_stock, reorder_point, last_updated, alert_flag) VALUES (105, 'C1', 15, 1, 8, 80, 16, '2023-10-27 10:20:00', 0);

3. Truy vấn dữ liệu ban đầu

SELECT *
FROM product_inventory_test;

-- Kết quả truy vấn
┌─product_id─┬─category_id─┬─stock_level─┬─is_active─┬─min_stock─┬─max_stock─┬─reorder_point─┬─last_updated─┬─alert_flag─┐
│       101 │ A1         │         50 │         1 │        10 │      100 │           20 │ 2023-10-27   │         0 │
│       102 │ A2         │         75 │         1 │        15 │      150 │           30 │ 2023-10-27   │         0 │
│       103 │ B1         │         30 │         1 │         5 │       50 │           10 │ 2023-10-27   │         0 │
│       104 │ B2         │         90 │         1 │        20 │      200 │           40 │ 2023-10-27   │         0 │
│       105 │ C1         │         15 │         1 │         8 │       80 │           16 │ 2023-10-27   │         0 │
└───────────┴────────────┴─────────────┴───────────┴──────────┴──────────┴──────────────┴──────────────┴───────────┘

4. Cập nhật cột Int32 (hoạt động bình thường)

Cập nhật cột `is_active` để kiểm tra chức năng cập nhật hoạt động đúng.

ALTER TABLE product_inventory_test UPDATE is_active = 0 WHERE product_id = 101;

-- Truy vấn sau khi cập nhật
SELECT *
FROM product_inventory_test
WHERE product_id = 101;

-- Kết quả truy vấn
┌─product_id─┬─category_id─┬─stock_level─┬─is_active─┬─min_stock─┬─max_stock─┬─reorder_point─┬─last_updated─┬─alert_flag─┐
│       101 │ A1         │         50 │         0 │        10 │      100 │           20 │ 2023-10-27   │         0 │
└───────────┴────────────┴─────────────┴───────────┴──────────┴──────────┴──────────────┴──────────────┴───────────┘

5. Cập nhật cột Nullable(Int32) (lỗi xảy ra)

Bây giờ, hãy thử cập nhật cột `alert_flag` có kiểu `Nullable(Int32)` với giá trị mới là `15`.

ALTER TABLE product_inventory_test UPDATE alert_flag = 15 WHERE product_id = 103;

-- Truy vấn sau khi cập nhật
SELECT *
FROM product_inventory_test
WHERE product_id = 103;

-- Kết quả truy vấn (bất ngờ)
┌─product_id─┬─category_id─┬─stock_level─┬─is_active─┬─min_stock─┬─max_stock─┬─reorder_point─┬─last_updated─┬─alert_flag─┐
│       103 │ B1         │         30 │         1 │         5 │       50 │           10 │ 2023-10-27   │   93147008 │
└───────────┴────────────┴─────────────┴───────────┴──────────┴──────────┴──────────────┴──────────────┴───────────┘

6. Cập nhật cột Nullable(Int32) khác (lỗi lặp lại)

Hãy thử cập nhật một cột `Nullable(Int32)` khác, ví dụ `reorder_point` với giá trị mới là `25`.

ALTER TABLE product_inventory_test UPDATE reorder_point = 25 WHERE product_id = 103;

-- Truy vấn sau khi cập nhật
SELECT *
FROM product_inventory_test
WHERE product_id = 103;

-- Kết quả truy vấn (lại là 93147008)
┌─product_id─┬─category_id─┬─stock_level─┬─is_active─┬─min_stock─┬─max_stock─┬─reorder_point─┬─last_updated─┬─alert_flag─┐
│       103 │ B1         │         30 │         1 │         5 │       50 │      93147008 │ 2023-10-27   │   93147008 │
└───────────┴────────────┴─────────────┴───────────┴──────────┴──────────┴──────────────┴──────────────┴───────────┘

Câu hỏi

Tại sao khi cập nhật các cột có kiểu dữ liệu `Nullable(Int32)`, kết quả luôn là giá trị cố định `93147008`, bất kể giá trị mới được cung cấp là gì?

Thẻ: ClickHouse sql kiểu dữ liệu Nullable cập nhật dữ liệu

Đăng vào ngày 13 tháng 7 lúc 22:15