Optimizing BRC Performances
When analyzing a product catalog, or more specifically a Configuration Process, several product rules will be described as explicitly as possible. When designing the eventual BRC however, questions can arise however: “what is the best BRC format?”, “what options give good performance?”.
Determining the BRC format to use
First of all, there is no such thing as a correct BRC format “in general”. Generally, the BRC format (matrix, formula, macro, product filter) depends on the semantics of the problem. The following table gives an overview of the semantically appropriate BRC format, regardless of other considerations (such as performance).
| FORMAT | USAGE |
|---|---|
| Matrix or SQL | A matrix is semantically good to express values or combinations of values such as in: A finite domain A list of possible combinations between 2 or more CPE Note that if the data supporting the business logic is maintained in Business Data Table because it can be reused by multiple BRCs, the SQL BRC is a good alternative to store the business constraint as a SQL query (the resulting matrix/constraint can only use "=" / "equal" operator in that case) |
| Formula | A formula is semantically interesting to express a relationship between aliases (and not the specific values) such as in: A calculation based on inputs that “always exist” (e.g. a calculated form property or a price) A “equals” constraint between 2 CPE A numerical constraint between 2 or more CPE possibly involving calculations (A > B, A <> B, A + B <= C, etc.) |
| Macro | A macro can be used for any of the above-mentioned usages, but will generally be used for all circumstances which cannot be covered by any of the above-mentioned formats. Typical examples are: Complex calculations and conditions (involving both conjunctions and disjunctions of sub-conditions for instance) Complex relationships using if..then..else clauses, while clauses, etc. Business Data Table (provided that the SQL BRC is not a more optimal choice) or external database lookup using SQL statements Java-based function calls Dynamically determining the output CPE (which was unknown beforehand) |
| FORMAT | USAGE |
|---|---|
| Product Filter | A product filter is semantically interesting to express a search on standard items in the Designer repository. Generally, this product filter is meant to provide a finite domain for an object-based form property. When the list of products is known and always the same or only dependent of a condition based on the identifiers of products, it could be more efficient (performance-wise) to use a matrix. |
Understanding operators
In matrix-based BRC, combinational problems can be expressed using different operators. These operators allow you to define lists or to define combinations in a more condensed way.
The following table shows an overview of the operator usage:
| OPERATOR | USAGE |
|---|---|
| =, <> | Can be used for the following alias types: Text, Long text Integer, Numeric, Monetary, Date Url, File Object Boolean |
| <, >, <=, >= | Can be used for the following alias types: Text, Long text Integer, Numeric, Monetary, Date Object |
| IN, NOT IN | Can be used for the following alias types: Text, Long text Integer, Numeric, Monetary, Date Url, File Object |
| LIKE, NOT LIKE | Can be used for the following alias types: Text, Long text Url, File |
| BETWEEN, < value <, <= value <, < value <= | Can be used for the following alias types: - Integer, Numeric, Monetary, Date |
Operators are very handy for maintenance reasons. In order to understand this, have a look at the
following example.
Example: compatibilities between the color and the number.
Suppose that the domain for the text-based form property “Color” contains the following values:
{RED, BLUE, BLACK, PINK, GREEN}, and that the domain for the integer-based form property “Number” is defined by a minimum value of 0 and a maximum value of 5.
At design-time, the possible (included) combinations can be expressed as follows:
| ALIASCOLOR | ALIASNUMBER | EXPLANATION | ||
|---|---|---|---|---|
| = | RED | = | 0 | |
| = | RED | = | 1 | |
| = | BLUE | = | 2 | |
| = | BLUE | = | 3 | |
| = | BLACK | = | 4 | |
| = | BLACK | = | 5 | |
| = | PINK | = | 4 | |
| = | PINK | = | 5 | |
| = | GREEN | = | 4 | |
| = | GREEN | = | 5 |
This representation may be the closest to reality at design-time, but is not very optimized from a maintenance point of view. Indeed, if at any time a color is added to the form property “Number”, the matrix will have to be updated in order to add the compatible lines. Secondly, in this small example only 10 lines have been shown, but in reality, thousands of combinations could be possible. Therefore, the following expression could be preferable:
| ALIASCOLOR | ALIASNUMBER | EXPLANATION | ||
|---|---|---|---|---|
| = | RED | < | 2 | EXP001 |
| = | BLUE | IN | {2,3} | |
| NOT IN | {RED, BLUE} | BETWEEN | [4..5] |
This representation has major advantages:
- If a new color is added, it is likely that the available numbers for that new color are the same as for another color. In this case, the impact can be limited: instead of adding a line for every possible combination, just change the impact lines.
- For instance, if the color “YELLOW” is compatible with 4 and 5, no changes will have to be made.
- For instance, if the color “GREY” is compatible with 2 and 3, the only necessary change is to update “=BLUE” to “IN {BLUE, GREY}”.
- If the exploded matrix contains thousands of records, this kind of expression could be more readable.Warning: It can be interesting to use operators other then “=” in order to improve readability or to facilitate maintenance.
In the Designer, operators can be specified on the line level or on the alias level (for matrix BRC).
For instance, the former table can be specified as follows:
| = | ALIASCOLOR | = | ALIASNUMBER | EXPLANATION |
|---|---|---|---|---|
| = | RED | = | 0 | |
| = | RED | = | 1 | |
| = | BLUE | = | 2 | |
| = | BLUE | = | 3 | |
| = | BLACK | = | 4 | |
| = | BLACK | = | 5 | |
| = | PINK | = | 4 | |
| = | PINK | = | 5 | |
| = | GREEN | = | 4 | |
| = | GREEN | = | 5 |
In this case, the operators on the line-level will be inherited automatically from the header level. This is important for performance reasons.
The “empty” operator
There is a special operator which can be used: the “empty” operator. This operator can be used to say that all values in a certain domain are applicable.
In the previous example, suppose that the color “PURPLE” is added, and that this color is compatible with ALL numbers. Also suppose that the number “6” is added, and that this number is compatible with ALL colors. The matrix will can now be represented as follows:
| = | ALIASCOLOR | = | ALIASNUMBER | EXPLANATION |
|---|---|---|---|---|
| = | RED | = | 0 | |
| = | RED | = | 1 | |
| = | BLUE | = | 2 | |
| = | BLUE | = | 3 | |
| = | BLACK | = | 4 | |
| = | BLACK | = | 5 | |
| = | PINK | = | 4 | |
| = | PINK | = | 5 | |
| = | GREEN | = | 4 | |
| = | GREEN | = | 5 |
| = | ALIASCOLOR | = | ALIASNUMBER | EXPLANATION |
|---|---|---|---|---|
| = | PURPLE | = | 6 |
Inclusions versus exclusions
The previous exercises showed the possible combinations between a color and a number. The list of combinations was limited, but what happens if thousands of combinations would be present?
Obviously, the usage of operators would help; however, there is another possibility.
Suppose that all colors (RED, BLUE, BLACK, PINK, GREEN, PURPLE) are compatible with almost all numbers between 0 and 1000, with individual exceptions per color. In this case, a simple list would end up in thousands of possibilities. The resulting BRC would be tagged as “managing inclusions”.
- Define a domain (based on a lookup in the column)
- Filter (or constrain) an previously defined domain, by applying the combinations
However, this case can easily be managed using exclusions. In this case, the resulting table would look about the same but has semantically speaking a totally different meaning: it lists the combinations which are invalid!
| = | ALIASCOLOR | = | ALIASNUMBER | EXPLANATION |
|---|---|---|---|---|
| = | RED | = | 100 | |
| = | RED | = | 122 | |
| = | BLUE | = | 302 | |
| = | BLUE | = | 403 | |
| = | BLACK | = | 102 |
| = | ALIASCOLOR | = | ALIASNUMBER | EXPLANATION |
|---|---|---|---|---|
| = | BLACK | = | 122 | |
| = | PINK | = | 959 | |
| = | PINK | = | 999 | |
| = | GREEN | = | 94 |
BRC normalization
When designing a BRC, the following question often comes up: “which aliases should I put in my BRC?”. The answer to this is composed of 2 elements:
- The semantics of the BRC, and
- The normalization of the BRC
Let’s have a deeper look into these elements. The first element is very simple to express:
In other words: the aliases involved in a business rule have to reflect reality as close as reasonably possible. If a business rule involves the answers to 4 form properties, the BRC should have 4 aliases, not more, not less. Fewer aliases would mean that an important relationship has been forgotten, and that the resulting BRC is semantically wrong. More aliases would mean that redundancy has found its way in the BRC, and that the BRC should be “normalized”.
Example
Suppose that you buy a new car. This car has 2 types of engine: gasoline and diesel. There are 3 “pack levels”: standard, comfort and sport. The alloy wheels that can be chosen depend on both the engine as well as the pack:
| = | AENGINE | = | APACK | = | AWHEEL |
|---|---|---|---|---|---|
| = | GASOLINE | = | STANDARD | = | 16 INCH |
| = | AENGINE | = | APACK | = | AWHEEL |
|---|---|---|---|---|---|
| = | GASOLINE | = | COMFORT | = | 17 INCH |
| = | GASOLINE | = | SPORT | = | 18 INCH |
| = | DIESEL | = | STANDARD | = | 15 INCH |
| = | DIESEL | = | STANDARD | = | 16 INCH |
| = | DIESEL | = | ECO | = | 16 INCH |
| = | DIESEL | = | SPORT | = | 18 INCH |
In this setup, it is clear that this relationship is normalized, because the wheel clearly depends on the engine as well as the pack level. However if you consider the following example, things are different:
| = | AENGINE | = | APACK | = | AWHEEL |
|---|---|---|---|---|---|
| = | GASOLINE | = | STANDARD | = | 16 INCH |
| = | GASOLINE | = | STANDARD | = | 15 INCH |
| = | GASOLINE | = | COMFORT | = | 17 INCH |
| = | GASOLINE | = | SPORT | = | 18 INCH |
| = | DIESEL | = | STANDARD | = | 15 INCH |
| = | AENGINE | = | APACK | = | AWHEEL |
|---|---|---|---|---|---|
| = | DIESEL | = | STANDARD | = | 16 INCH |
| = | DIESEL | = | ECO | = | 16 INCH |
| = | DIESEL | = | SPORT | = | 18 INCH |
In this case, if you would mask the “engine” in the relationship, you see that the domains for the wheel are “only” dependent on the pack level. This is where semantics come into play, because only the semantics of the product or business rule are able to tell you if the column “engine” is necessary in the relationship or not. From a pure theoretical normalization point of view, it could be interesting to take out the engine column, and replace the ternary BRC by 2 binary BRC:
| = | APACK | = | AWHEEL |
|---|---|---|---|
| = | STANDARD | = | 16 INCH |
| = | STANDARD | = | 15 INCH |
| = | COMFORT | = | 17 INCH |
| = | SPORT | = | 18 INCH |
| = | ECO | = | 16 INCH |
and
| = | AENGINE | = | APACK |
|---|---|---|---|
| = | GASOLINE | = | STANDARD |
| = | GASOLINE | = | COMFORT |
| = | GASOLINE | = | SPORT |
| = | DIESEL | = | STANDARD |
| = | DIESEL | = | ECO |
| = | DIESEL | = | SPORT |
However, what happens if tomorrow the marketing department tells you that the “15 inch” wheel is no longer available for diesel engines? By over-normalizing your BRC, you now end up having a maintenance issue: instead of merely added or removing lines, you now have to change the BRC structure.
The final message is thus the following:
Do not: Note that a BRC has to be meaningful. It is not recommended to use for example generic BRCs extracting data from a BDT / Standard Items BP values to determine static information such as existence, visibility states, domains, default values, etc.
