Update tech_docs/database/sql_guide.md
This commit is contained in:
@@ -482,4 +482,219 @@ conn.close()
|
||||
- **SQLite Official Documentation**: [https://sqlite.org/docs.html](https://sqlite.org/docs.html)
|
||||
- **SQLite Tutorial**: [https://www.sqlitetutorial.net/](https://www.sqlitetutorial.net/)
|
||||
|
||||
By following these steps and utilizing the resources mentioned, you'll be well on your way to mastering SQLite3 for your data projects.
|
||||
By following these steps and utilizing the resources mentioned, you'll be well on your way to mastering SQLite3 for your data projects.
|
||||
|
||||
---
|
||||
|
||||
Here's a comprehensive SQL coding standards document, aligned with the principles and structure we've used for HTML, Bash, and Python.
|
||||
|
||||
-----
|
||||
|
||||
# SQL Coding Standards Documentation
|
||||
|
||||
## Introduction
|
||||
|
||||
This document outlines our conventions and best practices for writing **SQL (Structured Query Language) queries, stored procedures, functions, and database schemas**. Adhering to these standards ensures our SQL code is **consistent, readable, maintainable, and performs optimally**. This approach fosters **seamless team collaboration**, **reduces debugging time**, and **improves overall database reliability and longevity**.
|
||||
|
||||
-----
|
||||
|
||||
## Formatting and Readability
|
||||
|
||||
Consistent formatting is paramount for understanding complex SQL statements.
|
||||
|
||||
### 1\. Indentation
|
||||
|
||||
* **Spaces over Tabs**: Use **4 spaces** for indentation. Configure your editor to convert tabs to spaces.
|
||||
* **Logical Blocks**: Indent clauses within statements (e.g., `SELECT` lists, `JOIN` conditions, `WHERE` clauses) to show hierarchy and structure.
|
||||
* **Usage**:
|
||||
```sql
|
||||
SELECT
|
||||
CustomerID,
|
||||
FirstName,
|
||||
LastName,
|
||||
OrderDate
|
||||
FROM
|
||||
Customers c
|
||||
JOIN
|
||||
Orders o ON c.CustomerID = o.CustomerID
|
||||
WHERE
|
||||
OrderDate >= '2024-01-01'
|
||||
AND TotalAmount > 100
|
||||
ORDER BY
|
||||
OrderDate DESC;
|
||||
```
|
||||
|
||||
### 2\. Capitalization
|
||||
|
||||
* **Keywords Uppercase**: SQL keywords (e.g., `SELECT`, `FROM`, `WHERE`, `JOIN`, `AND`, `OR`, `CREATE`, `TABLE`, `INSERT`, `UPDATE`, `DELETE`) should be in **UPPERCASE**.
|
||||
* **Identifiers (Tables, Columns, Aliases) Consistent Case**: Use a consistent case (e.g., `PascalCase` or `snake_case`) for table names, column names, and aliases. This document will primarily use `PascalCase` for table/column names in examples, but consistency is key within a project.
|
||||
* **Usage**:
|
||||
```sql
|
||||
SELECT
|
||||
ProductName,
|
||||
UnitPrice AS Price
|
||||
FROM
|
||||
Products;
|
||||
```
|
||||
|
||||
### 3\. Line Breaks and Spacing
|
||||
|
||||
* **One Clause Per Line**: Generally, place each major clause (`SELECT`, `FROM`, `WHERE`, `GROUP BY`, `ORDER BY`, `LIMIT`/`TOP`) on a new line.
|
||||
* **Commas**: In `SELECT` lists, place the comma *before* the column name on the subsequent line.
|
||||
* **Benefit**: Makes it easy to comment out or reorder columns without dealing with trailing commas.
|
||||
* **Usage**:
|
||||
```sql
|
||||
SELECT
|
||||
CustomerID
|
||||
, FirstName
|
||||
, LastName
|
||||
FROM
|
||||
Customers;
|
||||
```
|
||||
* **Operators**: Use spaces around operators (`=`, `+`, `>`, `AND`, `OR`, `IN`, `LIKE`).
|
||||
* **Usage**: `WHERE Price > 100`, `JOIN Table2 ON T1.ID = T2.ID`
|
||||
|
||||
-----
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
Consistent naming makes database objects and their components easy to identify and understand.
|
||||
|
||||
### 1\. Tables
|
||||
|
||||
* **Plural Nouns**: Use plural nouns.
|
||||
* **PascalCase (preferred) or snake\_case**: Be consistent. `PascalCase` (e.g., `OrderItems`) or `snake_case` (e.g., `order_items`).
|
||||
* **Avoid Prefixes**: Avoid redundant prefixes like `tbl_`.
|
||||
* **Usage**: `Customers`, `Products`, `OrderItems`
|
||||
|
||||
### 2\. Columns
|
||||
|
||||
* **Singular Nouns**: Use singular nouns.
|
||||
* **PascalCase (preferred) or snake\_case**: Be consistent with table naming.
|
||||
* **Primary Keys**: Suffix primary key columns with `ID` (e.g., `CustomerID`, `ProductID`).
|
||||
* **Foreign Keys**: Suffix foreign key columns with `ID` and prefix with the related table's singular name (e.g., `CustomerID` in `Orders` table, referencing `Customers.CustomerID`).
|
||||
* **Usage**: `FirstName`, `OrderDate`, `CustomerID`, `ProductID`
|
||||
|
||||
### 3\. Stored Procedures and Functions
|
||||
|
||||
* **Verb-Noun Structure**: Use a verb indicating the action, followed by a noun indicating the object.
|
||||
* **Prefixes**: Use `usp_` for stored procedures (User Stored Procedure) and `ufn_` for user-defined functions.
|
||||
* **PascalCase (preferred) or snake\_case**: Consistent with other naming.
|
||||
* **Usage**: `usp_GetCustomerOrders`, `ufn_CalculateTotalSales`
|
||||
|
||||
### 4\. Views
|
||||
|
||||
* **Prefixes**: Use `vw_` for views.
|
||||
* **PascalCase (preferred) or snake\_case**: Consistent.
|
||||
* **Descriptive Nouns**: Name should describe the data the view represents.
|
||||
* **Usage**: `vw_ActiveCustomers`, `vw_ProductSalesSummary`
|
||||
|
||||
### 5\. Indexes
|
||||
|
||||
* **Prefixes**: Use `IX_` for non-clustered indexes, `PK_` for primary key constraints (which often create clustered indexes), `UQ_` for unique constraints.
|
||||
* **Naming Convention**: `[Prefix]_[TableName]_[ColumnNames]`
|
||||
* **Usage**: `IX_Orders_OrderDate`, `PK_Customers_CustomerID`, `UQ_Products_SKU`
|
||||
|
||||
-----
|
||||
|
||||
## Comments
|
||||
|
||||
Good commenting explains the "why" and complex parts of your SQL.
|
||||
|
||||
* **Block Comments (`/* ... */`)**:
|
||||
* **Description**: Use for multi-line comments or for commenting out larger blocks of code. Ideal for script headers, complex logic explanations, or temporary disabling of code.
|
||||
* **Usage**:
|
||||
```sql
|
||||
/*
|
||||
This query retrieves all active customers
|
||||
who have placed an order in the last 30 days.
|
||||
It joins Customers and Orders tables.
|
||||
*/
|
||||
SELECT ...
|
||||
```
|
||||
* **Single-Line Comments (`--`)**:
|
||||
* **Description**: Use for single-line explanations or inline comments. Explain **why** a specific condition or calculation is used.
|
||||
* **Usage**:
|
||||
```sql
|
||||
SELECT
|
||||
ProductName,
|
||||
(UnitPrice * Quantity) AS LineTotal -- Calculate the total for each line item
|
||||
FROM
|
||||
OrderItems
|
||||
WHERE
|
||||
OrderDate >= GETDATE() - 30; -- Only consider orders from the last 30 days
|
||||
```
|
||||
|
||||
-----
|
||||
|
||||
## Best Practices and Principles
|
||||
|
||||
These principles guide our overall approach to writing effective, performant, and maintainable SQL code.
|
||||
|
||||
### 1\. Simplicity and Clarity
|
||||
|
||||
* **Break Down Complex Queries**: For very complex queries, consider breaking them down using Common Table Expressions (CTEs) (`WITH ... AS (...)`) or views to improve readability.
|
||||
* **Avoid `SELECT *`**: Always explicitly list the columns you need.
|
||||
* **Benefit**: Prevents fetching unnecessary data, makes the query intent clear, protects against schema changes (e.g., new columns breaking application code), and can improve performance.
|
||||
* **Usage**: `SELECT CustomerID, FirstName, LastName FROM Customers;`
|
||||
|
||||
### 2\. Performance Considerations
|
||||
|
||||
* **Use Joins Appropriately**: Understand the differences between `INNER JOIN`, `LEFT JOIN`, `RIGHT JOIN`, `FULL OUTER JOIN`. Choose the most appropriate join type based on your data relationships.
|
||||
* **Index Usage**: Design and use indexes strategically to improve query performance on frequently queried columns (especially in `WHERE`, `JOIN`, `ORDER BY`, `GROUP BY` clauses). However, avoid over-indexing, as it can degrade write performance.
|
||||
* **Avoid Functions in `WHERE` Clauses**: Applying functions to columns in `WHERE` or `JOIN` clauses (e.g., `WHERE YEAR(OrderDate) = 2024`) can prevent the database from using indexes on those columns.
|
||||
* **Instead**: Use range conditions (e.g., `WHERE OrderDate >= '2024-01-01' AND OrderDate < '2025-01-01'`).
|
||||
* **`LIMIT`/`TOP` for Paging**: Use `LIMIT` (MySQL, PostgreSQL) or `TOP` (SQL Server) for efficient paging and to prevent fetching excessive data.
|
||||
|
||||
### 3\. Data Integrity and Constraints
|
||||
|
||||
* **Primary Keys**: Every table should have a primary key to uniquely identify rows.
|
||||
* **Foreign Keys**: Use foreign keys to enforce referential integrity between tables.
|
||||
* **Constraints**: Implement `NOT NULL`, `UNIQUE`, `CHECK` constraints to enforce data validity rules at the database level.
|
||||
* **Benefit**: Ensures data quality and consistency, simplifies application logic.
|
||||
|
||||
### 4\. Transactions
|
||||
|
||||
* **ACID Properties**: For operations involving multiple DML (Data Manipulation Language) statements (e.g., `INSERT`, `UPDATE`, `DELETE`) that must succeed or fail as a single unit, use transactions (`BEGIN TRANSACTION`, `COMMIT`, `ROLLBACK`).
|
||||
* **Benefit**: Ensures Atomicity, Consistency, Isolation, Durability (ACID) for database operations.
|
||||
* **Usage**:
|
||||
```sql
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
INSERT INTO Orders (CustomerID, OrderDate, TotalAmount) VALUES (1, GETDATE(), 150.00);
|
||||
INSERT INTO OrderItems (OrderID, ProductID, Quantity, UnitPrice) VALUES (SCOPE_IDENTITY(), 101, 1, 150.00); -- Example for SQL Server
|
||||
|
||||
-- Or for PostgreSQL/MySQL:
|
||||
-- INSERT INTO OrderItems (OrderID, ProductID, Quantity, UnitPrice) VALUES (LAST_INSERT_ID(), 101, 1, 150.00);
|
||||
|
||||
IF @@ERROR <> 0
|
||||
BEGIN
|
||||
ROLLBACK TRANSACTION;
|
||||
PRINT 'Transaction failed!';
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
COMMIT TRANSACTION;
|
||||
PRINT 'Transaction committed successfully.';
|
||||
END;
|
||||
```
|
||||
|
||||
### 5\. Security
|
||||
|
||||
* **Least Privilege Principle**: Grant users and applications only the minimum necessary permissions on database objects.
|
||||
* **Avoid Dynamic SQL Injection**: Be extremely cautious when constructing SQL queries dynamically based on user input. Use parameterized queries or stored procedures to prevent SQL injection attacks.
|
||||
* **Usage (Conceptual - depends on client library/ORM)**:
|
||||
```sql
|
||||
-- BAD (Vulnerable to SQL Injection):
|
||||
-- query = "SELECT * FROM Users WHERE Username = '" + username + "'"
|
||||
|
||||
-- GOOD (Parameterized Query):
|
||||
-- query = "SELECT * FROM Users WHERE Username = %s"
|
||||
-- cursor.execute(query, (username,))
|
||||
```
|
||||
|
||||
-----
|
||||
|
||||
## Conclusion
|
||||
|
||||
By diligently applying these **SQL coding standards**, we ensure our database interactions are not only functional but also **highly readable, maintainable, and performant**. This commitment to quality coding practices promotes a more efficient development workflow, reduces technical debt, and strengthens the overall reliability and security of our data systems.
|
||||
Reference in New Issue
Block a user