Skip to content

Commit

Permalink
relational routing documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
chenson42 committed Jan 7, 2010
1 parent 74c0f50 commit 483f4c8
Showing 1 changed file with 56 additions and 5 deletions.
Expand Up @@ -314,12 +314,12 @@ values('item', 'corp-2-store', 1, current_timestamp, current_timestamp);
]]></programlisting>
</para>
</section>

<section id="basic-route-column-match">
<title>Column Router</title>
<para>
Sometimes requirements may exist that require data to be routed based on the current value or the old value of a
column on the table that is being routed. Column routers are configured by setting the router_type column on the <link linkend="router">router</link> table
column in the table that is being routed. Column routers are configured by setting the router_type column on the <link linkend="router">router</link> table
to 'column' and setting the router_expression column to an equality expression that represents the
the expected value of the column.
</para>
Expand Down Expand Up @@ -374,11 +374,62 @@ values('corp-2-store','corp', 'store', 'column', 'STORE_ID=:EXTERNAL_ID', curren
<![CDATA[insert into SYM_ROUTER
(router_id, source_node_group_id, target_node_group_id, router_type, router_expression, create_time, last_update_time)
values('corp-2-store','corp', 'store', 'column', 'STORE_ID=:REDIRECT_NODE', current_timestamp, current_timestamp);
]]></programlisting>

</para>


</section>

<section id="basic-route-relational">
<title>Relational Router</title>
<para>
Sometimes routing decisions need to be made based on data that is not in the current row being synchronized. Consider an
example where an Order table and a OrderLineItem table need to be routed to a specific store. The Order table has a column
named order_id and store_id. A store node has an external_id that is equal to the store_id on the Order table. OrderLineItem,
however, only has a foreign key to its order of order_id. In order to route it to the same desitnation, we need to reference
the master Order record.
</para>
<para>
There are two possible ways to route the OrderLineItem in SymmetricDS. One is to configure the 'subselect' router_type on the <link linkend="router">router</link> table
and the other is to configure an external_select on the <link linkend="trigger">trigger</link> table.
</para>
<para>
A 'subselect' is configured with a router_expression that is a SQL select statement that returns a result set of the node_ids that need routed to. Column tokens can
be used in the SQL expression and will be replaced with row column data. The overhead of using this router type is high because the 'subselect' runs for each row
that is routed. It should not be used for tables that have a lot of rows that are updated. It also has the disadvantage that if the Order master record is deleted,
then no results would be returned and routing would not happen.
</para>
<para>
Consider a table that needs to be routed to all nodes in the target group only when a status column is set to 'OK.' The following
SQL statement will insert a column router to accomplish that.
<programlisting>
<![CDATA[insert into SYM_ROUTER
(router_id, source_node_group_id, target_node_group_id, router_type, router_expression, create_time, last_update_time)
values('corp-2-store','corp', 'store', 'subselect', 'select c.node_id from sym_node c where c.node_group_id=:NODE_GROUP_ID and c.sync_enabled=1 and c.external_id in (select store_id from order where order_id=:ORDER_ID)', current_timestamp, current_timestamp);
]]></programlisting>
</para>
<para>
When using an external_select on the <link linkend="trigger">trigger</link> table, data is captured in the external_data column of the <link linkend="data">data</link> table when a trigger
fires. This 'external data' can then be used for routing by a router_type of 'column'. The advantage of this approach is that it is very unlikely that the master Order table
will have been deleted at the time any DML accures on the OrderLineItem table. It also is a bit more effcient than the 'subselect' approach, although the triggers produced do run
the extra external_select inline with application database updates.
</para>
<para>
In the following example, the store_id is captured from the Order table in the external_data column. EXTERNAL_DATA is always available for routing as a virtual column in a 'column'
router. The router is configured to route based on the captured EXTERNAL_DATA to all nodes whose external_id matches. Note that other supported node attribute token can also be
used for routing.
<programlisting>
<![CDATA[
insert into SYM_TRIGGER
(trigger_id,source_table_name,channel_id,external_select,last_update_time,create_time)
values('orderlineitem', 'orderlineitem', 'orderlineitem','select store_id from order where order_id=$(curTriggerValue).$(curColumnPrefix)order_id',current_timestamp, current_timestamp);
insert into SYM_ROUTER
(router_id, source_node_group_id, target_node_group_id, router_type, router_expression, create_time, last_update_time)
values('corp-2-store','corp', 'store', 'column', 'EXTERNAL_DATA=:EXTERNAL_ID', current_timestamp, current_timestamp);
]]></programlisting>
</para>
</section>


</chapter>

0 comments on commit 483f4c8

Please sign in to comment.