ClickHouse没有datimetime,如果是这种数据你们是如何处理的?
1 个回答
我疯狂地奔跑,只想为你承担一切的伤害,我竖起了山丘,不愿你看见我丑陋的脸庞。冰儿确实,ClickHouse 没有 **`DATETIME`** 类型,但它有 **`DateTime`** 和 **`DateTime64`** 类型。**ClickHouse 的 `DateTime` 类型相当于 MySQL 的 `DATETIME`**,但在底层存储方式上不同。 ## **1. ClickHouse 没有 `DATETIME` 类型** 在 MySQL、PostgreSQL 这类数据库中,`DATETIME` 是一种常见的数据类型: ```sql -- MySQL 中的 DATETIME CREATE TABLE example ( id INT PRIMARY KEY, event_time DATETIME ); ``` 但在 ClickHouse **没有 `DATETIME`** 这个关键字,如果你尝试使用,会报错: ```sql CREATE TABLE example ( id UInt64, event_time DATETIME -- ❌ 语法错误 ) ENGINE = MergeTree(); ``` ## **2. ClickHouse 使用 `DateTime` 类型** ClickHouse 提供了 `DateTime` 类型,它的作用类似于 MySQL 的 `DATETIME`,但底层实现不同: ```sql CREATE TABLE example ( id UInt64, event_time DateTime -- ✅ ClickHouse 里正确的时间类型 ) ENGINE = MergeTree() ORDER BY event_time; ``` 它的底层存储方式是 **Unix 时间戳(`UInt32`)**,只支持秒级精度。 ### **示例** ```sql INSERT INTO example VALUES (1, '2024-03-25 12:00:00'); SELECT * FROM example; ``` **返回** ``` ┌──id─┬──────────event_time─┐ │ 1 │ 2024-03-25 12:00:00 │ └─────┴────────────────────┘ ``` **等价于** ```sql INSERT INTO example VALUES (1, toDateTime('2024-03-25 12:00:00')); ``` ## **3. ClickHouse 使用 `DateTime64` 处理毫秒级** 如果你的数据有毫秒级甚至更高精度,`DateTime` 不够用,可以使用 `DateTime64`: ```sql CREATE TABLE example ( id UInt64, event_time DateTime64(3) -- ✅ ClickHouse 里支持毫秒 ) ENGINE = MergeTree() ORDER BY event_time; ``` `DateTime64(3)` 表示 **毫秒级** 精度(小数点后 3 位),`DateTime64(6)` 表示 **微秒级**(小数点后 6 位)。 **示例** ```sql INSERT INTO example VALUES (1, toDateTime64('2024-03-25 12:00:00.123', 3)); SELECT * FROM example; ``` **返回** ``` ┌──id─┬──────────event_time─┐ │ 1 │ 2024-03-25 12:00:00.123 │ └─────┴───────────────────────┘ ``` ## **4. `DateTime` 与 `DateTime64` 的区别** | 类型 | 精度 | 底层存储 | 示例 | |------|------|---------|------| | `DateTime` | 秒级 | `UInt32`(Unix 时间戳) | `2024-03-25 12:00:00` | | `DateTime64(3)` | 毫秒级 | `Decimal64(3)`(时间戳*1000) | `2024-03-25 12:00:00.123` | | `DateTime64(6)` | 微秒级 | `Decimal64(6)`(时间戳*1000000) | `2024-03-25 12:00:00.123456` | ## **5. 如果数据是 Unix 时间戳,如何处理?** 很多日志或外部数据存的是 Unix 时间戳(秒级或毫秒级),可以用 ClickHouse 的转换函数: ### **存 `UInt32` 并转换** ```sql CREATE TABLE example ( id UInt64, event_time UInt32 -- 存储 Unix 时间戳(秒级) ) ENGINE = MergeTree() ORDER BY event_time; ``` **查询时转换** ```sql SELECT id, fromUnixTimestamp(event_time) AS event_time_formatted FROM example; ``` 如果是 **毫秒级时间戳**(如 `1711363200123`),可以用 `fromUnixTimestamp64Milli()` 处理: ```sql SELECT fromUnixTimestamp64Milli(1711363200123); ``` ## **6. 总结** 1. **ClickHouse 没有 `DATETIME` 类型**,但 `DateTime` 可以代替它。 2. `DateTime` 精度是**秒级**,存储方式是 **UInt32(Unix 时间戳)**,更高效。 3. 如果需要 **毫秒级或微秒级**,可以用 `DateTime64(3)` 或 `DateTime64(6)`。 4. 如果存的是 **Unix 时间戳**(如 `1700000000`),可以用 `fromUnixTimestamp()` 进行转换。 5. **不要存 `String` 时间,查询时转换会影响性能!** 你可以根据业务需求选择 `DateTime`、`DateTime64` 或 Unix 时间戳的存储方式。编辑于 2025-06-27 20:20 •IP属地 北京举报评论收藏
公众号进入网站体验更佳

