When our company was acquired, tech folks from the holding company insisted we use their framework and architecture for all our future initiatives. This left little bit sour mouth and we wanted to compare, contrast and present merits and downsides of such approach. Architectural tradeoff analysis method (ATAM) came to our rescue in capturing architecture from software quality attributes standpoint. Here are some basics to anyone who intend to put this to use,
Step 1. Present the ATAM
Step 2. Present the business drivers
Step 3. Present the architecture
Step 4. Identify Architectural approaches
Step 5. Generate Quality Attribute utility tree
Step 6. Analyze Architectural approaches
Purpose:
The purpose of the ATAM is to assess the consequences of architectural decision alternatives in light of quality attributes. Choosing and designing an architecture that satisfies functional as well as quality attribute requirements (e.g., availability, security, and performance) is vital to the success of the system.
# risks: alternatives that might create future problems in some quality attribute
# sensitivity points: alternatives for which a slight change makes a significant difference in a quality attribute
# tradeoffs: decisions affecting more than one quality attribute
The ATAM is intended to analyze an architecture with respect to its quality attributes, not its functional correctness. Output from this process are
- Business Drivers:
- Architecture drivers - performance, high availability, time to market (modifiability), or high security.
- Constraints -
Business:
Technical:
More details can be found in http://www.sei.cmu.edu/pub/documents/07.reports/07tr015.pdf
Friday, September 11, 2009
Monday, September 7, 2009
XML Schema Design Styles
When it comes to schema design it can be approached from three different standpoints. Russian Doll, Salami Slice and Venetian Blind.
These first two designs represent opposite ends of the design spectrum.
To understand these designs it may help to think in terms of boxes, where a box represents an element or type:
* The Russian Doll design corresponds to having a single box, and it has nested within it boxes, which in turn have boxes nested within them, and so on. (boxes within boxes, just like a Russian Doll!)
* The Salami Slice design corresponds to having many separate boxes which are assembled together (separate boxes combined together, just like Salami slices brought together in a sandwich!)
Russian doll has following characteristics,
- Opaque content. The content of Book is opaque to other schemas, and to other parts of the same schema. The impact of this is that none of the types or elements within Book are reusable.
- Localized scope. The region of the schema where the Title and Author element declarations are applicable is localized to within the Book element. The impact of this is that if the schema has set elementFormDefault="unqualified" then the namespaces of Title and Author are hidden (localized) within the schema.
- Decoupled. With this design approach each component is self-contained (i.e., they don't interact with other components). Consequently, changes to the components will have limited impact. For example, if the components within Book changes it will have a limited impact since they are not coupled to components outside of Book.
- Cohesive. With this design approach all the related data is grouped together into self-contained components, i.e., the components are cohesive.
Salami has,
- Transparent content. The components which make up Book are visible to other schemas, and to other parts of the same schema. The impact of this is that the types and elements within Book are reusable.
- Global scope. All components have global scope. The impact of this is that, irrespective of the value of elementFormDefault, the namespaces of Title and Author will be exposed in instance documents.
- Verbose. Everything is laid out and clearly visible.
- Coupled. In our example we saw that the Book element depends on the Title and Author elements. If those elements were to change it would impact the Book element. Thus, this design produces a set of interconnected (coupled) components.
- Cohesive. With this design approach all the related data is also grouped together into self-contained components. Thus, the components are cohesive.
The two design approaches differ in a couple of important ways:
* The Russian Doll design facilitates hiding (localizing) namespace complexities. The Salami Slice design does not.
* The Salami Slice design facilitates component reuse. The Russian Doll design does not.
The Venetian provides,
- Maximum reuse. The primary component of reuse are type definitions.
- Maximum namespace hiding. Element declarations are nested within types, thus maximizing the potential for namespace hiding.
- Easy exposure switching. Whether namespaces are hidden (localized) in the schema or exposed in instance documents is controlled by the elementFormDefault switch.
- Coupled. This design generates a set of components which are interconnected (i.e., dependent).
- Cohesive. As with the other designs, the components group together related data. Thus, the components are cohesive.
So which one to choose? You can follow the following practice
[1] The Venetian Blind design is the one to choose where your schemas require the flexibility to turn namespace exposure on or off with a simple switch, and where component reuse is important.
[2] Where your task requires that you make available to instance document authors the option to use element substitution, then use the Salami Slice design.
[3] Where mimimizing size and coupling of components is of utmost concern then use the Russian Doll design.
These first two designs represent opposite ends of the design spectrum.
To understand these designs it may help to think in terms of boxes, where a box represents an element or type:
* The Russian Doll design corresponds to having a single box, and it has nested within it boxes, which in turn have boxes nested within them, and so on. (boxes within boxes, just like a Russian Doll!)
* The Salami Slice design corresponds to having many separate boxes which are assembled together (separate boxes combined together, just like Salami slices brought together in a sandwich!)
Russian doll has following characteristics,
- Opaque content. The content of Book is opaque to other schemas, and to other parts of the same schema. The impact of this is that none of the types or elements within Book are reusable.
- Localized scope. The region of the schema where the Title and Author element declarations are applicable is localized to within the Book element. The impact of this is that if the schema has set elementFormDefault="unqualified" then the namespaces of Title and Author are hidden (localized) within the schema.
- Decoupled. With this design approach each component is self-contained (i.e., they don't interact with other components). Consequently, changes to the components will have limited impact. For example, if the components within Book changes it will have a limited impact since they are not coupled to components outside of Book.
- Cohesive. With this design approach all the related data is grouped together into self-contained components, i.e., the components are cohesive.
Salami has,
- Transparent content. The components which make up Book are visible to other schemas, and to other parts of the same schema. The impact of this is that the types and elements within Book are reusable.
- Global scope. All components have global scope. The impact of this is that, irrespective of the value of elementFormDefault, the namespaces of Title and Author will be exposed in instance documents.
- Verbose. Everything is laid out and clearly visible.
- Coupled. In our example we saw that the Book element depends on the Title and Author elements. If those elements were to change it would impact the Book element. Thus, this design produces a set of interconnected (coupled) components.
- Cohesive. With this design approach all the related data is also grouped together into self-contained components. Thus, the components are cohesive.
The two design approaches differ in a couple of important ways:
* The Russian Doll design facilitates hiding (localizing) namespace complexities. The Salami Slice design does not.
* The Salami Slice design facilitates component reuse. The Russian Doll design does not.
The Venetian provides,
- Maximum reuse. The primary component of reuse are type definitions.
- Maximum namespace hiding. Element declarations are nested within types, thus maximizing the potential for namespace hiding.
- Easy exposure switching. Whether namespaces are hidden (localized) in the schema or exposed in instance documents is controlled by the elementFormDefault switch.
- Coupled. This design generates a set of components which are interconnected (i.e., dependent).
- Cohesive. As with the other designs, the components group together related data. Thus, the components are cohesive.
So which one to choose? You can follow the following practice
[1] The Venetian Blind design is the one to choose where your schemas require the flexibility to turn namespace exposure on or off with a simple switch, and where component reuse is important.
[2] Where your task requires that you make available to instance document authors the option to use element substitution, then use the Salami Slice design.
[3] Where mimimizing size and coupling of components is of utmost concern then use the Russian Doll design.
Labels:
XML Stuff
Friday, August 7, 2009
XML Databinding frameworks
When I began looking at the available data binding frameworks I was surprised to see that they didn't perform all that well compared with document models such as dom4j. This was contrary to my expectations, since the data binding approach actually reduces the amount of document information kept in memory -- a document model holds on to everything, while a data binding only needs the actual data. I thought that an approach that works with less data should generally be faster than one that works with more.
The aspect I questioned was the use of a SAX2 parser for unmarshalling documents. SAX2 is a very useful standard for parsing XML, but its event driven approach is not well suited to data binding and similar applications. The problem here is that the code processing the SAX2 events needs to maintain state information for everything it processes, and this adds both complexity and overhead.
I created the code that grew into JiBX to test some ways around these problematic aspects of the other data binding frameworks, and to experiment with extending the mapped binding approach beyond what's supported by Castor. Instead of reflection, JiBX uses byte code enhancement to add hooks into application code at project build time. Instead of SAX2, JiBX is based on a pull parser architecture (currently XMLPull). Rather than generating code from a DTD or Schema, JiBX works with a binding definition that associates user-supplied classes with XML structure.
These techniques are not unique to JiBX. Byte code enhancement is used by many JDO (Java Data Objects) implementations for basically the same purpose as in JiBX (to add access hooks to existing compiled code). The original JAXB code (since discarded) was based on a pull parser architecture similar to XMLPull. The mapped approach to data binding is supported (although with some limitations) by both Castor and Quick. Even though the individual techniques aren't new, the combination of them still makes for a very interesting alternative to the other data binding frameworks.
JiBX's use of a pull parser also helps keep the runtime small and efficient, as does its limited validation support - JiBX automatically checks many aspects of a document based on your mapping when unmarshalling, but does not support in-memory validation.
The aspect I questioned was the use of a SAX2 parser for unmarshalling documents. SAX2 is a very useful standard for parsing XML, but its event driven approach is not well suited to data binding and similar applications. The problem here is that the code processing the SAX2 events needs to maintain state information for everything it processes, and this adds both complexity and overhead.
I created the code that grew into JiBX to test some ways around these problematic aspects of the other data binding frameworks, and to experiment with extending the mapped binding approach beyond what's supported by Castor. Instead of reflection, JiBX uses byte code enhancement to add hooks into application code at project build time. Instead of SAX2, JiBX is based on a pull parser architecture (currently XMLPull). Rather than generating code from a DTD or Schema, JiBX works with a binding definition that associates user-supplied classes with XML structure.
These techniques are not unique to JiBX. Byte code enhancement is used by many JDO (Java Data Objects) implementations for basically the same purpose as in JiBX (to add access hooks to existing compiled code). The original JAXB code (since discarded) was based on a pull parser architecture similar to XMLPull. The mapped approach to data binding is supported (although with some limitations) by both Castor and Quick. Even though the individual techniques aren't new, the combination of them still makes for a very interesting alternative to the other data binding frameworks.
JiBX's use of a pull parser also helps keep the runtime small and efficient, as does its limited validation support - JiBX automatically checks many aspects of a document based on your mapping when unmarshalling, but does not support in-memory validation.
Labels:
XML Stuff
Friday, June 12, 2009
SQL Gotchas
While skimming my old zip drives I came across this interesting note that I had written years back related to SQL statements and prepared statements using iBatis framework. It was something to do with datatype of columns and implicit joins using prepared statement.
Problem: Issue of a static sql statement returns expected results, same statement issued as a prepared statment with parameters fails.
Static statement:
SELECT
nvl(sum(BATCHREL), 0) as CNT
FROM
userapplications a,
users b,
customers c
WHERE
a.USERRID = b.RID and
b.CUSTOMERKEY = c.RID AND
lower(c.ID) = '900100ev' AND
lower(b.ID) = 'admin1'
Prepared statment template:
SELECT
nvl(sum(BATCHREL), 0) as CNT
FROM
userapplications a,
users b,
customers c
WHERE
a.USERRID = b.RID and
b.CUSTOMERKEY = c.RID AND
lower(c.ID) = ? AND
lower(b.ID) = ?
Parameter values: '900100ev','admin1'
What I saw happening:
The c.id metadata was CHAR(20) and did not match the parameter passed in using prepared stmt, unless I padded it with spaces (to meet the length), however when I chose a literal string it worked w/out issues. I had to modify the prepared statement as follows (and it works)
SELECT
nvl(sum(BATCHREL), 0) as CNT
FROM
userapplications a,
users b,
customers c
WHERE
a.USERRID = b.RID and
b.CUSTOMERKEY = c.RID AND
RTRIM(lower(c.ID)) = #companyid# AND
lower(b.ID) = #operatorid#
Parameter values: '900100ev','admin1'
Problem: Issue of a static sql statement returns expected results, same statement issued as a prepared statment with parameters fails.
Static statement:
SELECT
nvl(sum(BATCHREL), 0) as CNT
FROM
userapplications a,
users b,
customers c
WHERE
a.USERRID = b.RID and
b.CUSTOMERKEY = c.RID AND
lower(c.ID) = '900100ev' AND
lower(b.ID) = 'admin1'
Prepared statment template:
SELECT
nvl(sum(BATCHREL), 0) as CNT
FROM
userapplications a,
users b,
customers c
WHERE
a.USERRID = b.RID and
b.CUSTOMERKEY = c.RID AND
lower(c.ID) = ? AND
lower(b.ID) = ?
Parameter values: '900100ev','admin1'
What I saw happening:
The c.id metadata was CHAR(20) and did not match the parameter passed in using prepared stmt, unless I padded it with spaces (to meet the length), however when I chose a literal string it worked w/out issues. I had to modify the prepared statement as follows (and it works)
SELECT
nvl(sum(BATCHREL), 0) as CNT
FROM
userapplications a,
users b,
customers c
WHERE
a.USERRID = b.RID and
b.CUSTOMERKEY = c.RID AND
RTRIM(lower(c.ID)) = #companyid# AND
lower(b.ID) = #operatorid#
Parameter values: '900100ev','admin1'
Labels:
DB Rant
Thursday, June 11, 2009
DB Naming Conventions
1. Basic Naming Conventions
The rules for naming all database objects (including table, view, column and index names) will follow those basic naming rules imposed by Database. These rules are defined as follows:
• Use a maximum of thirty (30) characters
• Do not use quotation marks in names
• Comprise names using only letters, digits and the underscore (_)
• Use underscores (_) for visual clarity
• Begin names with a letter
• Do not duplicate an Database reserved word
• Do not duplicate the name of another database object
• Use nouns, rather than verbs
• Be descriptive, yet as short as possible
• Use standard abbreviations
• Be unambiguous
2. Object Naming Conventions Imposed by Database
Abbreviations should be used for any object name including PL/SQL program variables. Object names should be a maximum of thirty characters long with these exceptions:
• Names of databases are limited to eight (8) characters
• Names of database links can be as long as 128 characters
• Object names should not contain quotation marks
• Object names are not case-sensitive
• Names can only contain alphanumeric characters from the database character set and the characters _, $, and #. The use of $ and # is strongly discouraged. Names of database links can also contain periods (.) and at-signs (@)
• Object names should contain underscores (_) for visual clarity
• Object names must begin with a letter
• Object names must not duplicate a database reserved word
• **Synonym** Must not duplicate the name of another database object
• Object names should use nouns instead of verbs
• Object names should be as descriptive and as short as possible
• Object names should use standard abbreviations when required
• Object names should not be ambiguous
Object Type Naming Convention Example:
Sequences SEQ_
30 char max size. For table Customer, column customer_id sequence name would be SEQ_CUSTOMER_ID
Table Name Naming close to ORM mapping. Max 30 char.
Suitable name for easy understanding. CONSUMER_PROFILE (instead of saying just consumer define more about the nature of table for which its used. Consumer_profile will differ from consumer_address)
View Name V_
30 char max size. V_CONSUMER_PROFILE
V_CONSUMER_ADDRESS etc
Indexes PK/FK/NU/UK_
30 Char max size FK (foreign key), PK (primary key), NU (non unique key), UK (unique key)
A foreign key index on the Consumer_profile table: FK_consumer_profile
For a primary key index on consumer_profile table: PK_CONSUMER_PROFILE
Constraint names PK/FK_ A FK and PK Constraint on the TBL_SOURCE table will be FK__ and PK_ respectively.
Columns Each table can have a 4 char prefix and this prefix shall be attached to each column of the table. CONSUMER_PROFILE table can have the 4 char prefix as CONP. The column can be CONP_PROFILE_ID etc.
Schema Names 8 char to 10 char QDPTLDB. One schema for all portals.
Synonyms Same as the database object name for which synonym will be created. Consumer_profile for QDPTLDB.CONSUMER_PROFILE table.
3. Database Table Column Names
The column names must be unique, meaningful and readily understood by anyone working with the table in order to make the development and maintenance of these applications as easy as possible.
• Use descriptive names.
• Words should be separated by underscore.
• Be consistent in abbreviations and in the use of singular and plural forms.
Column Purpose Data Type Column Name Guidelines
To store date DATE XXX_…._TS
To store numeric number NUMBER XXX_…._NUM
To store character number VARCHAR XXX_…_V
To store character flag VARCHAR XXX_…._FLG
To store character codes VARCHAR XXX_…_CD
To store char description VARCHAR XXX_…_DESC
To store int INT XXX_…_INT
To store float FLOAT XXX_…_FLT
To store real REAL XXX_…_RL
N.B: Credits to my lead for sharing such wonderful information
The rules for naming all database objects (including table, view, column and index names) will follow those basic naming rules imposed by Database. These rules are defined as follows:
• Use a maximum of thirty (30) characters
• Do not use quotation marks in names
• Comprise names using only letters, digits and the underscore (_)
• Use underscores (_) for visual clarity
• Begin names with a letter
• Do not duplicate an Database reserved word
• Do not duplicate the name of another database object
• Use nouns, rather than verbs
• Be descriptive, yet as short as possible
• Use standard abbreviations
• Be unambiguous
2. Object Naming Conventions Imposed by Database
Abbreviations should be used for any object name including PL/SQL program variables. Object names should be a maximum of thirty characters long with these exceptions:
• Names of databases are limited to eight (8) characters
• Names of database links can be as long as 128 characters
• Object names should not contain quotation marks
• Object names are not case-sensitive
• Names can only contain alphanumeric characters from the database character set and the characters _, $, and #. The use of $ and # is strongly discouraged. Names of database links can also contain periods (.) and at-signs (@)
• Object names should contain underscores (_) for visual clarity
• Object names must begin with a letter
• Object names must not duplicate a database reserved word
• **Synonym** Must not duplicate the name of another database object
• Object names should use nouns instead of verbs
• Object names should be as descriptive and as short as possible
• Object names should use standard abbreviations when required
• Object names should not be ambiguous
Object Type Naming Convention Example:
Sequences SEQ_
30 char max size. For table Customer, column customer_id sequence name would be SEQ_CUSTOMER_ID
Table Name Naming close to ORM mapping. Max 30 char.
Suitable name for easy understanding. CONSUMER_PROFILE (instead of saying just consumer define more about the nature of table for which its used. Consumer_profile will differ from consumer_address)
View Name V_
30 char max size. V_CONSUMER_PROFILE
V_CONSUMER_ADDRESS etc
Indexes PK/FK/NU/UK_
30 Char max size FK (foreign key), PK (primary key), NU (non unique key), UK (unique key)
A foreign key index on the Consumer_profile table: FK_consumer_profile
For a primary key index on consumer_profile table: PK_CONSUMER_PROFILE
Constraint names PK/FK_
Columns Each table can have a 4 char prefix and this prefix shall be attached to each column of the table. CONSUMER_PROFILE table can have the 4 char prefix as CONP. The column can be CONP_PROFILE_ID etc.
Schema Names 8 char to 10 char QDPTLDB. One schema for all portals.
Synonyms Same as the database object name for which synonym will be created. Consumer_profile for QDPTLDB.CONSUMER_PROFILE table.
3. Database Table Column Names
The column names must be unique, meaningful and readily understood by anyone working with the table in order to make the development and maintenance of these applications as easy as possible.
• Use descriptive names.
• Words should be separated by underscore.
• Be consistent in abbreviations and in the use of singular and plural forms.
Column Purpose Data Type Column Name Guidelines
To store date DATE XXX_…._TS
To store numeric number NUMBER XXX_…._NUM
To store character number VARCHAR XXX_…_V
To store character flag VARCHAR XXX_…._FLG
To store character codes VARCHAR XXX_…_CD
To store char description VARCHAR XXX_…_DESC
To store int INT XXX_…_INT
To store float FLOAT XXX_…_FLT
To store real REAL XXX_…_RL
N.B: Credits to my lead for sharing such wonderful information
Labels:
DB Rant
Subscribe to:
Posts (Atom)