A constraint naming standard is important for one primary reason: The SYS_* name Oracle assigns to unnamed constraints is not very understandable. By correctly naming all constraints, we can quickly associate a particular constraint with our data model. This gives us two real advantages:
We can quickly identify and fix any errors
We can reliably modify or drop constraints
Why do we need a naming convention? Oracle limits names, in general, to 30 characters, which is hardly enough for a human-readable constraint name.
We propose the following naming convention for all constraints, with the following abbreviations taken from the Oracle documentation. Note that we shortened all of the constraint abbreviations to two characters to save room.
<table name>_<column_name>_<constraint abbreviation>
In reality, this won't be possible because of the character limitation on names inside Oracle. When the name is too long, we will follow these steps in order:
Abbreviate the table name with the table's initials (for example, users -> u and users_contact -> uc).
Truncate the column name until it fits.
create table example_topics ( topic_id integer constraint example_topics_topic_id_pk primary key ); create table constraint_naming_example ( example_id integer constraint cne_example_id_pk primary key, one_line_description varchar(100) constraint cne_one_line_desc_nn not null, body clob, up_to_date_p char(1) default('t') constraint cne_up_to_date_p_check check(up_to_date_p in ('t','f')), topic_id constraint cne_topic_id_nn not null constraint cne_topic_id_fk references example_topics, -- Define table level constraint constraint cne_example_id_one_line_unq unique(example_id, one_line_description) ); |
Example B-1. Example of Constraint Name
Note | |
---|---|
|
Naming primary keys might not have any obvious advantages. However, in Example B-2, the primary key helps make the SQL query clearer.
SQL> set autotrace traceonly explain; SQL> select * from constraint_naming_example, example_topics where constraint_naming_example.topic_id = example_topics.topic_id; Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 NESTED LOOPS 2 1 TABLE ACCESS (FULL) OF 'CONSTRAINT_NAMING_EXAMPLE' 3 1 INDEX (UNIQUE SCAN) OF 'EXAMPLE_TOPICS_TOPIC_ID_PK' (UNIQUE) |
Example B-2. Primary Key Naming
Being able to see EXAMPLE_TOPICS_TOPIC_ID_PK in the trace helps us to know exactly which table Oracle is querying.
If we had not named the constraints, the execution plan would look like:
Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 NESTED LOOPS 2 1 TABLE ACCESS (FULL) OF 'CONSTRAINT_NAMING_EXAMPLE' 3 1 INDEX (UNIQUE SCAN) OF 'SYS_C00140971' (UNIQUE) |
The SYS_C00140971 by itself provides no information as to which index is being used in this query, and more importantly, the name of this constraint will vary from database to database.
Mark Lindsey (<[email protected]>) provided another good reason to name primary keys and unique constraints. Oracle creates an index for every primary key and unique constraint with the same name as the constraint. It is an unfortunate DBA who has to wrestle with storage management of tens of mysteriously-named indexes.
Red Hat Applications developers are undecided on whether or not to name not null constraints. If you want to name them, please do so and follow the above naming standard. Currently, naming not null constraints is not a requirement of WAF.
Note | |
---|---|
Naming the not null constraints does not help immediately in error debugging (for example the error will say something like Cannot insert null value into column). We do recommend naming not null constraints to be consistent in our naming of all constraints. |
Data model upgrade scripts are a crucial part of database-based applications. Standards help to ensure that upgrade scripts behave correctly and consistently. This helps save time in development, maintenance, and support.
Tip | |
---|---|
An upgrade script should be written anytime that a change is made to a component's sql creation script that results in a different schema and/or data set. The new upgrade script should be written so that, when applied to the previous creation script, it results in the same schema and data set. |
Every component should have exactly zero or one upgrade script per release per supported database. However, an upgrade script may source other files.
Upgrade scripts go in an upgrade/ directory below the directory containing the corresponding creation script. The name of the file should be <component-name>-<old-version-name>-<new-version-name>.sql.
Example:
cms/sql/oracle-se/upgrade/cms-4.6.4-4.6.5.sql |
Extending this process farther, there should be a single upgrade script for all of WAF per version. This upgrade script lives in kernel/sql/oracle-se/upgrade and is called core-platform-<old-version-name> -<new-version-name>.sql.
Similar to core-platform-create.sql, this script will not have its own SQL commands, but will simply source other files. Updating this script is the responsibility of each component developer.