Store multidimensional array in database: relational or multidimensional?

后端 未结 6 1760
栀梦
栀梦 2021-02-14 02:14

I have read numerous posts along the lines of multidimensional to single dimension, multidimensional database, and so on, but none of the answers helped. I did

6条回答
  •  盖世英雄少女心
    2021-02-14 02:38

    This approach does not depend on the existence of a path or parent column. It is relational not recursive.

    Since the table is static create a materialized view containing just the leaves to make searching faster:

    create materialized view leave as
    select cell
    from (
        select cell,
            lag(cell,1,cell) over (order by cell desc) not like cell || '%' as leave
        from t
    ) s
    where leave;
    
    table leave;
     cell 
    ------
     CCCE
     CCCA
     CCBE
     CCBC
     BEDA
     BDDA
     BDCE
     BDCB
     BAA
     AEEB
     AEA
     AB
     AAC
     AAA
    

    A materialized view is computed once at creation not at each query like a plain view. Create an index to speed it up:

    create index cell_index on leave(cell);
    

    If eventually the source table is altered just refresh the view:

    refresh materialized view leave;
    

    The search function receives text and returns a text array:

    create or replace function get_descendants(c text)
    returns text[] as $$
        select array_agg(distinct l order by l)
        from (
            select left(cell, generate_series(length(c), length(cell))) as l
            from leave
            where cell like c || '%'
        ) s;
    $$ language sql immutable strict;
    

    Pass the desired match to the function:

    select get_descendants('A');
              get_descendants          
    -----------------------------------
     {A,AA,AAA,AAC,AB,AE,AEA,AEE,AEEB}
    
    select get_descendants('AEE');
     get_descendants 
    -----------------
     {AEE,AEEB}
    

    Test data:

    create table t (cell text);
    insert into t (cell) values
    ('A'),
    ('AA'),
    ('AAA'),
    ('AAC'),
    ('AB'),
    ('AE'),
    ('AEA'),
    ('AEE'),
    ('AEEB'),
    ('B'),
    ('BA'),
    ('BAA'),
    ('BD'),
    ('BDC'),
    ('BDCB'),
    ('BDCE'),
    ('BDD'),
    ('BDDA'),
    ('BE'),
    ('BED'),
    ('BEDA'),
    ('C'),
    ('CC'),
    ('CCB'),
    ('CCBC'),
    ('CCBE'),
    ('CCC'),
    ('CCCA'),
    ('CCCE'),
    ('CE');
    

提交回复
热议问题