The goal of this style guide is to improve the readability and performance of SQL queries.
YYYY-MM-DD HH:MM:SS.SSSSS).WHERE clauses that can otherwise be derived./* and
closing */ where possible otherwise preceed comments with -- and finish
them with a new line.staff instead of employees or people instead of individuals.SELECT file_hash -- stored ssdeep hashFROM file_systemWHERE file_name = '.vimrc';
/* Updating the file record after writing to the file */UPDATE file_systemSET file_modified_date = '1980-02-22 13:19:01.00000',file_size = 209732WHERE file_name = '.vimrc';
first_name).SELECT first_nameFROM staff;
staff and employees.tbl or any other such descriptive prefix or Hungarian
notation.cars_mechanics prefer services.AS keyword—makes it easier to read as it is explicit.SUM() or AVG()) use the name you would give it were it
a column defined in the schema.SELECT first_name AS fnFROM staff AS s1JOIN students AS s2ON s2.mentor_id = s1.staff_num;SELECT SUM(s.monitor_tally) AS monitor_totalFROM staff AS s;
The following suffixes have a universal meaning ensuring the columns can be read and understood easily from SQL code. Use the correct suffix where appropriate.
_id—a unique identifier such as a column that is a primary key._status—flag value or some other status of any type such as
publication_status._total—the total or sum of a collection of values._num—denotes the field contains any kind of number._name—signifies a name such as first_name._seq—contains a contiguous sequence of values._date—denotes a column that contains the date of something._tally—a count._size—the size of something such as a file size or clothing._addr—an address for the record could be physical or intangible such as
ip_addr.Always use uppercase for the [reserved keywords][reserved-keywords]
like SELECT and WHERE.
It is best to avoid the abbreviated keywords and use the full length ones where
available (prefer ABSOLUTE to ABS).
Do not use database server specific keywords where an ANSI SQL keyword already exists performing the same function. This helps to make code more portable.
SELECT model_numFROM phones AS pWHERE p.release_date > '2014-09-30';
To make the code easier to read it is important that the correct compliment of spacing is used. Do not crowd code or remove natural language spaces.
Spaces should be used to line up the code so that the root keywords all end on the same character boundary. This forms a river down the middle making it easy for the readers eye to scan over the code and separate the keywords from the implementation detail.
SELECT f.average_height,f.average_diameterFROM flora AS fWHERE f.species_name = 'Banksia'OR f.species_name = 'Sheoak'OR f.species_name = 'Wattle';
Notice that SELECT, FROM, etc. are all right aligned while the actual column
names and implementation specific details are left aligned.
Although not exhaustive always include spaces:
=),)') where not within parentheses or with a trailing
comma or semicolon.SELECT a.title,a.release_date,a.recording_dateFROM albums AS aWHERE a.title = 'Charcoal Lane'OR a.title = 'The New Danger';
Always include newlines/vertical space:
AND or ORKeeping all the keywords aligned to the righthand side and the values left aligned creates a uniform gap down the middle of query. It makes it much easier to scan the query definition over quickly too.
INSERT INTO albums (title, release_date, recording_date)VALUES ('Charcoal Lane', '1990-01-01 01:01:01.00000', '1990-01-01 01:01:01.00000'),('The New Danger', '2008-01-01 01:01:01.00000', '1990-01-01 01:01:01.00000');UPDATE albumsSET release_date = '1990-01-01 01:01:01.00000'WHERE title = 'The New Danger';SELECT a.title,a.release_date, a.recording_date, a.production_date -- grouped dates togetherFROM albums AS aWHERE a.title = 'Charcoal Lane'OR a.title = 'The New Danger';
To ensure that SQL is readable it is important that standards of indentation are followed.
Joins should be indented to the other side of the river and grouped with a new line where necessary.
SELECT r.last_nameFROM riders AS rINNER JOIN bikes AS bON r.bike_vin_num = b.vin_numAND b.engines > 2INNER JOIN crew AS cON r.crew_chief_last_name = c.last_nameAND c.chief = 'Y';
BETWEEN where possible instead of combining multiple statements
with AND.IN() instead of multiple OR clauses.CASE
expression. CASE statements can be nested to form more complex logical structures.UNION clauses and temporary tables where possible. If the
schema can be optimised to remove the reliance on these features then it most
likely should be.SELECT CASE postcodeWHEN 'BN1' THEN 'Brighton'WHEN 'EH1' THEN 'Edinburgh'END AS cityFROM office_locationsWHERE country = 'United Kingdom'AND opening_time BETWEEN 8 AND 9AND postcode IN ('EH1', 'BN1', 'NN1', 'KW1')
When declaring schema information it is also important to maintain human readable code. To facilitate this ensure the column definitions are ordered and grouped where it makes sense to do so.
Indent column definitions by four (4) spaces within the CREATE definition.
REAL or FLOAT types where it is strictly necessary for floating
point mathematics otherwise prefer NUMERIC and DECIMAL at all times. Floating point rounding errors are a nuisance!DECIMAL do not provide an INTEGER default value.NOT NULL statement.Constraints and their subset, keys, are a very important component of any database definition. They can quickly become very difficult to read and reason about though so it is important that a standard set of guidelines are followed.
Deciding the column(s) that will form the keys in the definition should be a carefully considered activity as it will effect performance and data integrity.
It is a reasoned and considered balancing act to be performed at the definition of a database. Should requirements evolve in the future it is possible to make changes to the definitions to keep them up to date.
Once the keys are decided it is possible to define them in the system using constraints along with field value validation.
UNIQUE, PRIMARY KEY
and FOREIGN KEY where the database vendor will generally supply sufficiently
intelligible names automatically.CREATE TABLE statement.CREATE TABLE definition.ON DELETE comes before ON UPDATE.NOT NULL definitions could start at the same
character position. This is not hard and fast, but it certainly makes the code
much easier to scan and read.LIKE and SIMILAR TO constraints to ensure the integrity of strings
where the format is known.CHECK() to prevent incorrect values entering the database or the silent truncation of data too large to fit the column definition. In the least it should check that the value is greater than zero in most cases.CHECK() constraints should be kept in separate clauses to ease debugging.(PRIMARY KEY (staff_num),staff_num INT(5) NOT NULL,first_name VARCHAR(100) NOT NULL,pens_in_drawer INT(2) NOT NULL,CONSTRAINT pens_in_drawer_rangeCHECK(pens_in_drawer >= 1 AND pens_in_drawer < 100));
UNION rather than just simply querying one table.If you want to become a SQL ninja, you should always review: