MariaDB 中按 ENUM 列分区的替代方案

问题描述 投票:0回答:1

出于性能原因,我想根据枚举字段对表进行分区。该表预计将包含大量数据,从应用程序的角度来看,在此枚举列上进行分区非常有意义。

这是我想做的一个最小的例子:

DROP TABLE IF EXISTS test_performance_data;
CREATE TABLE test_performance_data
(
    id            INT AUTO_INCREMENT PRIMARY KEY,
    resource_type ENUM ('campaign', 'ad_group', 'ad_item', 'keyword')
)
    PARTITION BY LIST COLUMNS (resource_type) (
        PARTITION campaigns VALUES IN ('campaign'),
        PARTITION ad_groups VALUES IN ('ad_group'),
        PARTITION ad_items VALUES IN ('ad_item'),
        PARTITION keywords VALUES IN ('keyword')
        );

不幸的是,这不起作用,因为据我了解,MariaDB 不支持枚举字段上的分区。我收到此错误:

字段“resource_type”属于此类分区不允许的类型

我尝试添加一个整数存储的生成列

partition_id
,但这也不起作用,因为根据我的理解,MariaDB 也不支持按生成列进行分区。这是我尝试过的:

DROP TABLE IF EXISTS test_performance_data;

CREATE TABLE test_performance_data
(
    id            INT AUTO_INCREMENT PRIMARY KEY,
    resource_type ENUM ('campaign', 'ad_group', 'ad_item', 'keyword'),
    partition_id  INT GENERATED ALWAYS AS (
        CASE 
            WHEN resource_type = 'campaign' THEN 1
            WHEN resource_type = 'ad_group' THEN 2
            WHEN resource_type = 'ad_item' THEN 3
            WHEN resource_type = 'keyword' THEN 4
        END
    ) STORED
)
PARTITION BY LIST (partition_id) (
    PARTITION campaigns VALUES IN (1),
    PARTITION ad_groups VALUES IN (2),
    PARTITION ad_items VALUES IN (3),
    PARTITION keywords VALUES IN (4)
);

这是我得到的错误:

(子)分区函数中不允许使用常量、随机或与时区相关的表达式

我真的很想将分区保留在数据库级别,这意味着如果我需要添加列,它将由数据库管理,而不是由应用程序管理。

我考虑过添加一个整数

partition_id
列,以及一个插入前和更新前触发器,根据枚举字段对其进行更新,但由于触发器的性能开销,我不确定这是一个好主意。

解决这个问题的最佳方法是什么?

PS:不确定是否相关,但就上下文而言,

resource_type
(与
resource_id
列一起)用于在 Laravel 中建模多态关系。
我正在使用 MariaDB 的
10.6.18-MariaDB-log
版本。

提前非常感谢您的回答。

sql laravel mariadb database-partitioning
1个回答
0
投票

ENUM
是一个转移注意力的话题。
PARTITION BY LIST
对性能几乎没有帮助。 最好有 composite 索引 starting
ENUM
(或其他数据类型)。 根据不同的查询,将 PK 安排为复合的可能也是有益的。

为了进一步讨论,请提供您希望分区帮助解决的查询、其他重要查询以及

CREATE TABLE
的其余部分。 (然后我可以建议一组索引来帮助查询。它可能涉及建议对
PRIMARY KEY
进行更改。)

© www.soinside.com 2019 - 2024. All rights reserved.