2.7 Rivers and Vertical Spacing 37 expression, but its DECODE() function is quite close to it and can be substituted in older versions of Oracle. 2.7 Rivers and Vertical Spacing When you look at a magazine or newspaper, you will notice that the text is set in a column that is even on both sides. This is called justified text, as opposed to ragged right or ragged left text. Extra spacing is added to each line to justify the text, but if this extra spacing appears in the same location on several rows, you get rivers. A river is a vertical open space in text, and it is considered to be bad typography. You want to read text from left to right, top to bottom, with a visual break at the indentation or new line that marks the start of a paragraph. A river pulls your eye downward and makes the text more difficult to read. It is easy to set up what typographers call rivers in the program code in a monospace font because you can add spacing as needed, but that same downward river effect aligns code on a vertical axis and makes the program easier to read. SELECT I1.incident_type, IPC.defendant_type, R1.notes, O1.start_date, O1.end_date, O1.reported_datetime, IPC.urn FROM Incidents AS I1, IPC, Recommendations AS R1, Offences AS O1, WHERE IPC.recommendation_id = R1.recommendation_id AND IPC.urn = O1.urn AND IPC.urn = I1.urn AND IPC.urn = R1.urn AND I1.urn = O1.urn; versus no river: SELECT I1.incident_type, IPC.defendant_type, R1.notes, O1.start_date, O1.end_date, O1.reported_datetime, IPC.urn FROM Incidents AS I1, IPC, Recommendations AS R1, Offences AS O1, WHERE IPC.recommendation_id = R1.recommendation_id AND IPC.urn = O1.urn AND IPC.urn = I1.urn AND IPC.urn = R1.urn AND I1.urn = O1.urn; 38 CHAPTER 2: FONTS, PUNCTUATION, AND SPACING 2.8 Indentation When you have to indent in block-structured 3GL programming languages, use three spaces. A single space is too short to be read as anything but a word separator. Two spaces will work because that is what you were probably taught to use in typing classes at the end of a sentence, but three spaces or a new line is clearly a paragraph to the reader. Indenting five or more spaces actually hurts readability. The eye has to skip over too far to grab the code. In particular, the use of an eight- space tab character is historical. The early Teletype machines had 80 characters per line and set tabs at eight spaces for mechanical reasons. That became the definition when we moved to electronic terminals. The rule for SQL is that rivers override what we were doing in the old 3GL languages. Rationale: What we need in data manipulation language (DML) is a balance of indentation and the use of rivers to the logical nesting. Note how each subquery has a river to hold it together and that the subquery is placed against the river. SELECT DISTINCT pilot FROM PilotSkills AS PS1 WHERE NOT EXISTS (SELECT * FROM Hangar WHERE NOT EXISTS (SELECT * FROM PilotSkills AS PS2 WHERE PS1.pilot = PS2.pilot AND PS2.plane = Hangar.plane)); Exceptions: A subquery is always inside parentheses, so one can make a case that the closing parentheses should align vertically with its mate. SELECT DISTINCT pilot FROM PilotSkills AS PS1 WHERE NOT EXISTS (SELECT * 2.9 Use Line Spacing to Group Statements 39 FROM Hangar WHERE NOT EXISTS (SELECT * FROM PilotSkills AS PS2 WHERE PS1.pilot = PS2.pilot AND PS2.plane = Hangar.plane ) ); The advantage is that you can quickly find the limits of the subquery but at the cost of extra lines that hold only one or two tokens. When you have a group of related columns in the SELECT clause list or other places, then use the three-space rule to indent the members of the group when you have to go to a second line: SELECT C1.cust_name, C1.street_address, C1.city, C1.state, C1.zip, P1.payment_1, P1.payment_2, P1.payment_3, P1.payment_4, P1.payment_5, P1.payment_6, P1.payment_7, P1.payment_8, P1.payment_9, payment_10, FROM Customers AS C1, Payments AS P1 WHERE C1.cust_id = P1.cust_id; The customer columns are on one line, while the 10 payments are split over three lines with an indentation to group them. 2.9 Use Line Spacing to Group Statements Rationale: Use one new line between related statements and two new lines between separate steps in the same process. Clusters of related code on a page show the reader which statements perform each step of a process. It is also a good idea to introduce each step with a high-level comment, but we will get into that later. As an experiment to demonstrate how important visual clustering is, make some flash cards with some red circles on them. On one set of flash cards, arrange the spots in the patterns in which they appear on a double nine set of dominoes. On a second set of flash cards, put the spots on at random. Show the cards to your subjects for one second each and call out the number of the card. Ask them to write down the number of spots on 40 CHAPTER 2: FONTS, PUNCTUATION, AND SPACING each card. When there is no arrangement, most people start having problems at five spots and almost nobody can handle eight or more randomly arranged cards. However, nine spots in a three-by-three arrangement present no problems. Even the 10 spots on a playing card are easy to count because they are broken into two clusters of five spots. Exceptions: The double spacing between steps can be optional if it breaks up the flow of the code. CHAPTER 3 Data Declaration Language “[I need] Data! Data! Data! I can’t make bricks without clay.” —Sherlock Holmes (fictional detective of author Sir Arthur Conan Doyle) “Smart data structures and dumb code works a lot better than the other way round.” —Eric S. Raymond I BELIEVE THAT MOST of the bad SQL queries in the world are the result of bad schema design. A bad schema can be ambiguous, require extra work to fetch data, and not return valid results even when good data was input into it. Let’s start with the syntax rules that should be followed when writing data declaration language (DDL), and then in the following chapters, talk about the content and semantics of the DDL. 3.1 Put the Default in the Right Place Rationale: The DEFAULT constraint appears after the data type and NOT NULL constraint appears after the DEFAULT value. The SQL-92 standard requires that ordering, but most products allow you to place the DEFAULT either after the data type or after the . FONTS, PUNCTUATION, AND SPACING 2.8 Indentation When you have to indent in block-structured 3GL programming languages, use three spaces. A single space is too short to be read as anything but. mechanical reasons. That became the definition when we moved to electronic terminals. The rule for SQL is that rivers override what we were doing in the old 3GL languages. Rationale: What we. better than the other way round.” —Eric S. Raymond I BELIEVE THAT MOST of the bad SQL queries in the world are the result of bad schema design. A bad schema can be ambiguous, require