Question

here again to ask your help guys!

I have two questions for you and two sql tables:

  • TABLE_1

    [ ID_T1, T1_NAME,      T1_VALUE   ]
    
        0 |   name_t1_0 |  value_t1_0
        1 |   name_t1_1 |  value_t1_1
        2 |   name_t1_2 |  value_t1_2
        3 |   name_t1_3 |  value_t1_3
    
  • TABLE_2

    [ ID_T2,  ID_T1_IN_T2,   T2_NAME,   T2_VALUE    ]
    
        0        | 0 |    name_t2_00 | value_t2_00
        1        | 0 |    name_t2_10 | value_t2_10
        2        | 0 |    name_t2_20 | value_t2_20
        3        | 0 |    name_t2_30 | value_t2_30
        0        | 1 |    name_t2_01 | value_t2_01
        1        | 1 |    name_t2_11 | value_t2_11
        0        | 2 |    name_t2_02 | value_t2_02
        1        | 2 |    name_t2_12 | value_t2_12
    

ID_T1 is an unique progressive index. Each ID_T1 in TABLE_1 can be present in ID_T1_IN_T2 column N times.

ID_T2 is a progressive index associated to each ID_T1.

This means that for each row in TABLE_1 we can have N rows in TABLE_2.

  • Question #1: how can I auto update ID_T1_IN_T2 values when a row is removed from TABLE_1 ?

Example: remove row with ID_T1 = 0 from TABLE 1. Expected result is the following (ID_T1 after 0 are decreased and so with ID_T1_IN_T2)

TABLE_1

 [ ID_T1,  T1_NAME,    T1_VALUE   ]
    0 |   name_t1_1 |  value_t1_1
    1 |   name_t1_2 |  value_t1_2
    2 |   name_t1_3 |  value_t1_3

TABLE_2

[ ID_T2,  ID_T1_IN_T2,   T2_NAME,     T2_VALUE    ]
    0        | 0 |      name_t2_01 |  value_t2_01
    1        | 0 |      name_t2_11 |  value_t2_11
    0        | 1 |      name_t2_02 |  value_t2_02
    1        | 1 |      name_t2_12 |  value_t2_12

  • Question #2: how can I auto update ID_T2 values when a row is removed from?

Example: remove row with ID_T2 = 0 and ID_T1_IN_T2=0 from the just-updated TABLE_2. Expected result is the following (ID_T2 after 0 are decreased and ID_T1_IN_T2 remains the same)

[ ID_T2,  ID_T1_IN_T2,   T2_NAME,     T2_VALUE    ]
    0        | 0 |      name_t2_11 |  value_t2_11
    0        | 1 |      name_t2_02 |  value_t2_02
    1        | 1 |      name_t2_12 |  value_t2_12

What do you recommend to do in these cases?

Note that dropping tables and recreating them is not considered as a solution because it's dirty and veeeery low performing (and that's the solution I have temporary adopted).

No correct solution

OTHER TIPS

Your C++ application is not using a good database approach. I suggest you to work around this behaviour with views and triggers.

Example:

Your main tables become T1 and T2:

CREATE TABLE T1(ID, T1_NAME, T1_VALUE);
CREATE TABLE T2(ID, ID_T1, T2_NAME, T2_VALUE);

Those ID become fixed! You should not change them!

Next, auxiliary views, mapping real ID to dynamic ones:

CREATE VIEW T1_IDX AS SELECT DISTINCT ID, (SELECT COUNT() FROM (SELECT DISTINCT ID FROM T1 AS _ WHERE ID<T1.ID)) AS ID_T1 FROM T1;
CREATE VIEW T2_IDX AS SELECT DISTINCT ID, (SELECT COUNT() FROM (SELECT DISTINCT ID FROM T2 AS _ WHERE ID<T2.ID)) AS ID_T2 FROM T2;

TABLE_1 and TABLE_2 become emulated as views:

CREATE VIEW TABLE_1 AS
    SELECT ID_T1, T1_NAME, T1_VALUE FROM T1
    JOIN T1_IDX ON T1.ID=T1_IDX.ID;
CREATE VIEW TABLE_2 AS
    SELECT ID_T2, T1_IDX.ID_T1 AS ID_T1_IN_T2, T2_NAME, T2_VALUE FROM T2
    JOIN T2_IDX ON T2.ID=T2_IDX.ID
    JOIN T1_IDX ON T2.ID_T1=T1_IDX.ID;

And DELETE statement on TABLE_1 become mapped with following TRIGGER:

CREATE TRIGGER TABLE_1_DELETE INSTEAD OF DELETE ON TABLE_1 BEGIN
    DELETE FROM T2 WHERE ID_T1 = (SELECT ID FROM T1_IDX WHERE ID_T1=OLD.ID_T1);
    DELETE FROM T1 WHERE ID = (SELECT ID FROM T1_IDX WHERE ID_T1=OLD.ID_T1);
END;

With this automation, your C++ application will see TABLE_1 with computed indexes, not real ones, and DELETE operation is handled by SQLite engine to operate on real tables.

Note: other operations on views, beyond SELECT and DELETE FROM TABLE_1, if needed, must be implemented as triggers!

Another simpler option.

Just add a trigger:

CREATE TRIGGER TABLE_1_DELETE AFTER DELETE ON TABLE_1 BEGIN
    UPDATE TABLE_1 SET ID_T1=ID_T1-1 WHERE ID_T1>OLD.ID_T1;
    -- DELETE FROM TABLE_2 WHERE ID_T1_IN_T2=OLD.ID_T1;
    UPDATE TABLE_2 SET ID_T1_IN_T2=ID_T1_IN_T2-1 WHERE ID_T1_IN_T2>OLD.ID_T1;
    END;
CREATE TRIGGER TABLE_2_DELETE AFTER DELETE ON TABLE_2 BEGIN
    UPDATE TABLE_2 SET ID_T2=ID_T2-1 WHERE ID_T2>OLD.ID_T2 AND ID_T1_IN_T2=OLD.ID_T1_IN_T2;
    END;

Those triggers will update indexes right after delete.

If you remove commented line, delete on TABLE_1 will also cause delete corresponding records in TABLE_2.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top