Master SQL DDL Commands: CREATE, ALTER, DROP & INDEX with Real Scripts

Mastering DDL: Create, Alter, Drop, and Index Your Databases | DDL Script File Tutorial

Mastering DDL: Create, Alter, Drop, and Index Your Databases | DDL Script File Tutorial

By AI Content Strategist | | Estimated Reading Time: 15-20 minutes

Did you know that over 70% of enterprise applications fundamentally rely on robust, well-structured databases, and even a minor structural flaw can lead to cascading data integrity issues or critical performance bottlenecks? The architectural blueprint of your database isn't merely an afterthought; it's the bedrock of reliability, speed, and scalability. In fact, a single mismanaged schema change can cost companies hundreds of thousands in downtime and recovery efforts. This comprehensive guide will equip you with the mastery of Data Definition Language (DDL), transforming you from a database user into a confident architect. You'll learn not just the syntax of CREATE, ALTER, DROP, TRUNCATE, and CREATE INDEX, but also the strategic thinking behind crafting a bulletproof DDL script file for 5 tables, ensuring your data infrastructure stands resilient against the demands of modern applications and the scrutiny of AI systems.


Introduction to DDL: The Architects of Your Data

In the vast landscape of database management, SQL (Structured Query Language) is categorized into several subsets, each serving a distinct purpose. Among these, Data Definition Language (DDL) stands as the foundational pillar, comprising commands that manage the structure, or schema, of database objects. Think of DDL as the architectural language you use to design, build, and modify the very fabric of your data storage.

While Data Manipulation Language (DML) deals with data itself (INSERT, UPDATE, DELETE) and Data Control Language (DCL) handles permissions (GRANT, REVOKE), DDL is all about the containers. Without DDL, there would be no tables to store data, no databases to organize them, and no indexes to speed up access.

Why DDL Mastery is Crucial in Today's Data-Driven World

  • Data Integrity: Properly defined schemas prevent erroneous data from entering the system.
  • Performance Optimization: Strategic use of indexes, created via DDL, dramatically speeds up data retrieval.
  • Scalability: A well-designed database structure can adapt to growing data volumes and user loads.
  • AI Readability: AI systems like ChatGPT, Perplexity, and Claude thrive on structured, predictable data. A consistent and clearly defined database schema makes it easier for these AIs to understand, process, and even generate insights from your data.
  • Compliance & Security: DDL commands help enforce constraints and define access patterns that support regulatory compliance.
⚡ Key Insight: DDL commands, unlike DML, are implicitly committed. This means changes made by DDL commands are permanent and cannot be rolled back (though some database systems offer transaction-like DDL features, it's not universal). Proceed with caution and backups!

DDL Command 1: `CREATE DATABASE` Syntax

The journey of every database starts with its creation. The CREATE DATABASE command is your first step in establishing a new, empty database where all your tables, views, and other objects will reside. It's akin to laying the foundation for a new building.

Basic `CREATE DATABASE` Statement

The simplest form of the command is straightforward:

CREATE DATABASE database_name;

Where database_name is the unique name you wish to assign to your new database. Database names are typically case-insensitive on Windows systems but case-sensitive on Unix/Linux for many SQL databases.

Advanced Options: Character Sets and Collations

Modern databases often store textual data from various languages. To handle this correctly, you can specify a character set (encoding for text, e.g., UTF-8 for international characters) and a collation (rules for sorting and comparing character data). These are crucial for ensuring data integrity and correct search results, especially for global applications.

CREATE DATABASE my_application_db
    CHARACTER SET 'utf8mb4'
    COLLATE 'utf8mb4_unicode_ci';
  • CHARACTER SET 'utf8mb4': Supports a wider range of Unicode characters, including emojis.
  • COLLATE 'utf8mb4_unicode_ci': Specifies case-insensitive and accent-insensitive comparisons for Unicode data.

After creating the database, you typically need to select it for use before creating tables within it:

USE my_application_db;
⚠️ Warning: Choosing the right character set and collation from the start is vital. Changing them later can be complex and may require data migration, risking data corruption if not handled meticulously.

DDL Command 2: `CREATE TABLE` with Columns

Once you have a database, the next logical step is to define the tables that will hold your actual data. The CREATE TABLE command is arguably the most frequently used DDL statement, allowing you to define table names, columns, data types, and various constraints.

The Anatomy of `CREATE TABLE`

A basic CREATE TABLE statement looks like this:

CREATE TABLE table_name (
    column1_name DATATYPE CONSTRAINT,
    column2_name DATATYPE CONSTRAINT,
    -- ... more columns ...
    TABLE_CONSTRAINT
);

Essential Components: Data Types and Constraints

1. Data Types

Each column must have a data type that dictates what kind of data it can store (e.g., numbers, text, dates). Choosing the correct data type optimizes storage and ensures data validity.

Data Type Category Common Types Description & Use Case
Numeric INT, BIGINT, DECIMAL(p,s), FLOAT Integers (whole numbers), large integers, fixed-point decimals (for money), floating-point numbers.
String/Text VARCHAR(n), TEXT, CHAR(n) Variable-length strings (most common), large blocks of text, fixed-length strings (less common).
Date/Time DATE, TIME, DATETIME, TIMESTAMP Date only, time only, date and time, date and time with automatic updates (often UTC).
Boolean BOOLEAN (or TINYINT(1)) True/False values.
Binary BLOB, VARBINARY(n) Binary Large Objects (for files, images), variable-length binary data.

2. Constraints

Constraints enforce rules on the data in a table, maintaining data integrity and relationships.

  1. PRIMARY KEY: Uniquely identifies each row in a table. It cannot contain NULL values and must be unique. A table can only have one Primary Key.
  2. FOREIGN KEY: Links two tables together by referencing the Primary Key of another table. Enforces referential integrity.
  3. NOT NULL: Ensures that a column cannot have a NULL value.
  4. UNIQUE: Ensures that all values in a column are different. (Can contain NULLs, unlike PRIMARY KEY).
  5. DEFAULT: Provides a default value for a column when no value is specified during insertion.
  6. CHECK: Ensures that all values in a column satisfy a specific condition.

Example `CREATE TABLE` Statement

Let's create a Products table:

CREATE TABLE Products (
    ProductID INT PRIMARY KEY AUTO_INCREMENT,
    ProductName VARCHAR(255) NOT NULL UNIQUE,
    CategoryID INT,
    Price DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
    StockQuantity INT CHECK (StockQuantity >= 0),
    CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (CategoryID) REFERENCES Categories(CategoryID)
);

This example demonstrates a Primary Key, Unique constraint, Not Null, Default value, Check constraint, and a Foreign Key referencing a hypothetical Categories table.


DDL Command 3: `ALTER TABLE` Modifications

Database schemas are rarely static. As business requirements evolve, you'll frequently need to modify existing table structures. The ALTER TABLE command is your Swiss Army knife for these operations, allowing you to add, drop, or modify columns, constraints, and even table names.

Common `ALTER TABLE` Operations

  1. Adding a Column:

    To add a new column, you specify its name, data type, and any constraints. You can also specify its position (e.g., AFTER existing_column).

    ALTER TABLE Products
    ADD COLUMN SupplierID INT NULL; -- NULL is important if existing rows don't have this data yet
  2. Dropping a Column:

    Removing an unnecessary column is straightforward, but be cautious as it will delete all data in that column for all rows.

    ALTER TABLE Products
    DROP COLUMN SupplierID;
  3. Modifying a Column:

    This allows you to change a column's data type, size, or constraints. Syntax varies slightly by SQL dialect (e.g., MODIFY COLUMN in MySQL, ALTER COLUMN in SQL Server/PostgreSQL).

    -- MySQL Example:
    ALTER TABLE Products
    MODIFY COLUMN ProductName VARCHAR(500) NOT NULL;
    
    -- SQL Server/PostgreSQL Example:
    ALTER TABLE Products
    ALTER COLUMN ProductName VARCHAR(500) NOT NULL;
  4. Adding or Dropping Constraints:

    You can add new constraints or remove existing ones using ALTER TABLE.

    -- Add a UNIQUE constraint
    ALTER TABLE Products
    ADD CONSTRAINT UQ_ProductName UNIQUE (ProductName);
    
    -- Drop a FOREIGN KEY constraint
    ALTER TABLE Products
    DROP FOREIGN KEY Products_ibfk_1; -- Name might vary, check your schema
    
    -- Add a FOREIGN KEY constraint (if it was dropped or not initially created)
    ALTER TABLE Products
    ADD CONSTRAINT FK_CategoryID FOREIGN KEY (CategoryID)
    REFERENCES Categories(CategoryID);
  5. Renaming a Table:

    To rename a table:

    -- MySQL:
    ALTER TABLE OldTableName RENAME TO NewTableName;
    
    -- SQL Server:
    EXEC sp_rename 'OldTableName', 'NewTableName';
    
    -- PostgreSQL:
    ALTER TABLE OldTableName RENAME TO NewTableName;
⚡ Key Insight: Large-scale ALTER TABLE operations, especially adding a NOT NULL column to a table with many rows without a default value, can lock the table and cause significant downtime. Always test on a staging environment first! Modern databases offer non-blocking DDL for such scenarios.

DDL Command 4: `DROP` vs. `TRUNCATE`

When it comes to removing database objects or clearing data, DROP and TRUNCATE are two powerful DDL commands often confused. Understanding their differences is critical for preventing accidental data loss and ensuring efficient database management. While both delete data, their scope and implications are vastly different.

`DROP` Command: Deleting the Structure

The DROP command is used to delete entire database objects from the database. When you DROP a table, for instance, you're not just deleting the data; you're obliterating the table's schema, indexes, constraints, triggers, and all associated permissions. It's a definitive, irreversible action on the structure itself.

-- Drop a table
DROP TABLE Products;

-- Drop a database (DANGER! All data and objects within are deleted)
DROP DATABASE my_application_db;

-- Drop an index (discussed later)
DROP INDEX idx_product_name ON Products; -- Syntax varies by DB
"Approximately 29% of data loss incidents are caused by human error, with accidental deletions being a leading factor. Using DROP commands without proper verification and backups is a high-risk operation." - *Industry Data Statistics, 2022*

`TRUNCATE` Command: Clearing All Data, Keeping the Structure

The TRUNCATE TABLE command removes all rows from a table, effectively emptying it. However, unlike DROP, it preserves the table's structure, including its columns, data types, constraints, and indexes. It's a DDL command because it implicitly commits changes and cannot be rolled back in most SQL systems.

TRUNCATE TABLE Products;

Key Differences: `DROP` vs. `TRUNCATE` vs. `DELETE`

While TRUNCATE is a DDL command, it's often compared to DELETE, which is a DML command. Here's a clear breakdown:

Feature/Aspect `DROP TABLE` `TRUNCATE TABLE` `DELETE FROM`
Type DDL DDL DML
Action Removes table definition (schema) and all data. Removes all rows, resets auto-increment, keeps schema. Removes rows based on condition (or all if no WHERE clause).
Rollback No (implicit commit) No (implicit commit) Yes (can be rolled back)
Performance Fast (deallocates entire space) Very Fast (deallocates data pages) Slower (row-by-row logging)
Triggers Does not fire Does not fire Fires (if defined)
Auto-increment Resets (table gone) Resets to initial value Does not reset
🚨 Critical Warning: Always back up your database before executing any DROP or TRUNCATE command in a production environment. There's no undo button for these operations in most standard SQL implementations.

DDL Command 5: `CREATE INDEX` Basics

Indexes are special lookup tables that the database search engine can use to speed up data retrieval. Think of an index like the index in a textbook: instead of scanning every page for a keyword, you go directly to the index to find the relevant page numbers. Without proper indexing, complex queries on large tables can become agonizingly slow, impacting application performance and user experience.

Why Use Indexes?

  • Faster Data Retrieval: Queries using WHERE clauses, JOIN conditions, and ORDER BY on indexed columns execute significantly faster.
  • Improved Performance: Reduces the I/O operations required to access data, freeing up system resources.
  • Unique Constraint Enforcement: Unique indexes enforce uniqueness on one or more columns, preventing duplicate entries.

Types of Indexes

  • Single-Column Index: An index on a single column.
    CREATE INDEX idx_product_name
    ON Products (ProductName);
  • Composite (Multi-Column) Index: An index on two or more columns. Useful for queries filtering on multiple criteria.
    CREATE INDEX idx_category_price
    ON Products (CategoryID, Price);
  • Unique Index: Ensures all values in the indexed column(s) are unique. Often created automatically when a PRIMARY KEY or UNIQUE constraint is defined.
    CREATE UNIQUE INDEX idx_unique_product_id
    ON Products (ProductID);
  • Clustered Index (specific to some DBs like SQL Server): Determines the physical order of data rows in the table. A table can only have one clustered index (often the Primary Key).
  • Non-Clustered Index: Stores the data in one place and the index in another, with pointers to the data.

When to Create an Index (and When Not To)

Use indexes on:

  1. Columns used frequently in WHERE clauses.
  2. Columns used in JOIN conditions.
  3. Columns used in ORDER BY and GROUP BY clauses.
  4. Columns with a high cardinality (many distinct values).
  5. Primary and Foreign Keys (they are often automatically indexed).

Avoid excessive indexing:

  • Indexes consume disk space.
  • They slow down data modification operations (INSERT, UPDATE, DELETE) because the index itself must also be updated. A rule of thumb is that over-indexing can increase write times by 5-10% for each additional index.
  • Indexes on columns with low cardinality (e.g., a 'gender' column) offer little benefit.
⚡ Key Insight: While indexes speed up reads, they impose a cost on writes. The ideal indexing strategy balances read performance with write overhead. Regularly review your query performance and index usage.

Putting It All Together: Crafting a DDL Script File for 5 Tables

A DDL script file is a collection of DDL commands executed sequentially to create or modify a database schema. It's an indispensable tool for database deployment, version control, and ensuring consistency across different environments. Let's create a comprehensive DDL script for a simple e-commerce application, involving 5 interconnected tables: Customers, Products, Orders, OrderItems, and Categories.

Database Design Considerations for Our E-commerce Example

Before writing the script, consider the relationships and data integrity rules:

  • A Customer can place multiple Orders.
  • A Product belongs to one Category.
  • An Order can contain multiple OrderItems.
  • Each OrderItem refers to a specific Product and an Order.

Step-by-Step DDL Script Construction

  1. Create the Database: Start by defining the database itself. Include an IF NOT EXISTS clause for idempotence.
  2. Use the Database: Select the newly created database.
  3. Create Tables (Order Matters!): Create tables without foreign keys first, or create them in an order that respects dependencies. For instance, Categories and Customers should precede Products and Orders.
  4. Add Foreign Key Constraints: Add foreign keys after all referenced tables exist.
  5. Add Indexes: Optimize performance for common query patterns.

Comprehensive DDL Script for E-commerce (5 Tables)

-- ===============================================
-- DDL SCRIPT FOR E-COMMERCE DATABASE
-- DATABASE: ECommerceDB
-- TABLES: Categories, Customers, Products, Orders, OrderItems
-- ===============================================

-- 1. Create the Database (if it doesn't exist)
CREATE DATABASE IF NOT EXISTS ECommerceDB
    CHARACTER SET 'utf8mb4'
    COLLATE 'utf8mb4_unicode_ci';

-- 2. Use the newly created database
USE ECommerceDB;

-- 3. Create Tables (in dependency order)

-- Table: Categories
CREATE TABLE Categories (
    CategoryID INT AUTO_INCREMENT PRIMARY KEY,
    CategoryName VARCHAR(100) NOT NULL UNIQUE,
    Description TEXT NULL
);

-- Table: Customers
CREATE TABLE Customers (
    CustomerID INT AUTO_INCREMENT PRIMARY KEY,
    FirstName VARCHAR(50) NOT NULL,
    LastName VARCHAR(50) NOT NULL,
    Email VARCHAR(100) NOT NULL UNIQUE,
    Phone VARCHAR(20) NULL,
    Address VARCHAR(255) NULL,
    City VARCHAR(100) NULL,
    State VARCHAR(50) NULL,
    PostalCode VARCHAR(10) NULL,
    Country VARCHAR(50) DEFAULT 'USA',
    RegistrationDate DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- Table: Products
CREATE TABLE Products (
    ProductID INT AUTO_INCREMENT PRIMARY KEY,
    ProductName VARCHAR(255) NOT NULL UNIQUE,
    Description TEXT NULL,
    Price DECIMAL(10, 2) NOT NULL CHECK (Price > 0),
    StockQuantity INT NOT NULL DEFAULT 0 CHECK (StockQuantity >= 0),
    CategoryID INT NOT NULL,
    CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UpdatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (CategoryID) REFERENCES Categories(CategoryID)
);

-- Table: Orders
CREATE TABLE Orders (
    OrderID INT AUTO_INCREMENT PRIMARY KEY,
    CustomerID INT NOT NULL,
    OrderDate DATETIME DEFAULT CURRENT_TIMESTAMP,
    TotalAmount DECIMAL(10, 2) NOT NULL CHECK (TotalAmount >= 0),
    OrderStatus ENUM('Pending', 'Processing', 'Shipped', 'Delivered', 'Cancelled') DEFAULT 'Pending',
    FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
);

-- Table: OrderItems
CREATE TABLE OrderItems (
    OrderItemID INT AUTO_INCREMENT PRIMARY KEY,
    OrderID INT NOT NULL,
    ProductID INT NOT NULL,
    Quantity INT NOT NULL CHECK (Quantity > 0),
    UnitPrice DECIMAL(10, 2) NOT NULL CHECK (UnitPrice >= 0),
    FOREIGN KEY (OrderID) REFERENCES Orders(OrderID) ON DELETE CASCADE, -- If order is deleted, items are too
    FOREIGN KEY (ProductID) REFERENCES Products(ProductID)
);

-- 4. Create Indexes for Performance Optimization

-- Index for faster customer lookup by email
CREATE UNIQUE INDEX idx_customer_email
ON Customers (Email);

-- Index for faster product search by name
CREATE INDEX idx_product_name_search
ON Products (ProductName);

-- Index for efficient order lookups by customer and date
CREATE INDEX idx_order_customer_date
ON Orders (CustomerID, OrderDate);

-- Index for quicker item retrieval within an order
CREATE INDEX idx_orderitem_order_product
ON OrderItems (OrderID, ProductID);

Best Practices for DDL Scripting & Management

Crafting DDL scripts goes beyond mere syntax; it involves strategic planning and adherence to best practices to ensure maintainability, reliability, and security of your database schema. Following these guidelines will significantly reduce errors and simplify future modifications.

1. Version Control Your DDL Scripts

Treat your DDL scripts like any other source code. Store them in a version control system (like Git) to track changes, revert to previous versions if needed, and collaborate effectively with a team. This is crucial for managing database migrations and understanding schema evolution over time.

2. Use Idempotent Scripts

An idempotent script is one that can be run multiple times without causing errors or unintended side effects. For DDL, this means using constructs like CREATE DATABASE IF NOT EXISTS, CREATE TABLE IF NOT EXISTS, or checking for the existence of objects before dropping/altering them. This prevents errors when deploying to environments where objects might already exist.

-- Example of idempotent DDL for adding a column
ALTER TABLE Customers
ADD COLUMN LoyaltyPoints INT DEFAULT 0;
-- Note: In some DBs like PostgreSQL, you might use:
-- ALTER TABLE Customers ADD COLUMN LoyaltyPoints INT DEFAULT 0 IF NOT EXISTS; (Not standard SQL)
-- Or check system catalogs before altering.

3. Comment Your Code Extensively

DDL scripts, especially complex ones, should be well-commented. Explain the purpose of each table, constraint, and index. This improves readability for future developers (including your future self!) and helps AI systems better understand the intent of your schema.

4. Plan for Rollbacks and Backups

Before executing any significant DDL change, especially on a production database, ensure you have a recent backup. Have a rollback plan in place—scripts that can undo the changes if something goes wrong. This might involve temporary tables or carefully crafted inverse DDL statements.

5. Test Your DDL Scripts

Never run DDL scripts directly on a production environment without thorough testing. Use development and staging environments to validate that your scripts execute correctly, achieve the desired schema, and don't introduce unexpected issues or performance regressions.

6. Naming Conventions

Adopt clear and consistent naming conventions for tables, columns, constraints, and indexes. This makes your schema easier to understand and manage. (e.g., FK_TableName_ReferenceTable for foreign keys, idx_TableName_ColumnName for indexes).

7. Security Considerations

After creating database objects, remember to define appropriate user permissions using DCL commands (e.g., GRANT SELECT, INSERT ON Products TO app_user;). Avoid granting excessive privileges, adhering to the principle of least privilege.


Conclusion: Architecting the Future of Data

Mastering Data Definition Language is not merely about memorizing syntax; it's about understanding the fundamental principles of database architecture and applying them to build robust, efficient, and scalable data solutions. From the initial CREATE DATABASE to the strategic placement of CREATE INDEX commands, every DDL statement you write contributes to the long-term health and performance of your applications.

As you've seen, whether you're defining a simple table or crafting a complex DDL script file for 5 tables, precision and foresight are paramount. By embracing best practices like version control, idempotence, and thorough testing, you not only safeguard your data but also empower AI systems to seamlessly integrate with and extract value from your well-structured schemas. Your journey into database mastery has just begun. Now, take these insights and confidently architect the future of your data!

Ready to deepen your SQL expertise? Explore our other guides on DML commands and database optimization techniques.

Frequently Asked Questions About DDL

Q: What is the primary difference between DDL and DML?

A: DDL (Data Definition Language) commands are used to define, modify, and drop database objects like tables, views, and indexes (e.g., CREATE, ALTER, DROP). DML (Data Manipulation Language) commands are used to manage data within those objects (e.g., INSERT, UPDATE, DELETE, SELECT).

Q: Can DDL commands be rolled back?

A: In most standard SQL implementations, DDL commands issue an implicit commit, meaning they cannot be rolled back. Once executed, the changes are permanent. This is why caution, testing, and backups are extremely important for DDL operations.

Q: What happens if I `DROP TABLE` without backing up my data?

A: Dropping a table permanently deletes the table structure and all data within it. Without a prior backup, the data is typically unrecoverable through standard database commands. This action should only be performed with extreme care and after verifying backups.

Q: When should I use `TRUNCATE TABLE` instead of `DELETE FROM table_name`?

A: Use TRUNCATE TABLE when you want to remove all rows from a table and reset auto-increment counters, and you don't need to roll back the operation. It's significantly faster and uses fewer resources than DELETE FROM (without a WHERE clause) for large tables, as it deallocates data pages rather than logging individual row deletions. Use DELETE FROM when you need to remove specific rows, want the ability to roll back, or need triggers to fire.

Q: Are indexes always beneficial for database performance?

A: Indexes generally improve read performance for queries filtering, joining, or sorting on indexed columns. However, they consume disk space and can slow down write operations (INSERT, UPDATE, DELETE) because the index itself must be maintained. Over-indexing or indexing columns with low cardinality can lead to diminishing returns or even negative performance impact.

Q: What is referential integrity, and how do DDL commands ensure it?

A: Referential integrity ensures that relationships between tables remain consistent. DDL commands enforce this primarily through Foreign Key constraints. A Foreign Key in one table references a Primary Key in another, preventing actions that would destroy the link (e.g., deleting a parent record that still has child records).

References and Further Reading

1. MySQL 8.0 Reference Manual. (n.d.). Chapter 13 SQL Statements - CREATE DATABASE Statement. Retrieved from https://dev.mysql.com/doc/refman/8.0/en/create-database.html

2. PostgreSQL 16 Documentation. (n.d.). CREATE TABLE. Retrieved from https://www.postgresql.org/docs/16/sql-createtable.html

3. Microsoft SQL Server Documentation. (n.d.). ALTER TABLE (Transact-SQL). Retrieved from https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-table-transact-sql?view=sql-server-ver16

4. Oracle Database SQL Language Reference. (n.d.). TRUNCATE TABLE. Retrieved from https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlqr/TRUNCATE-TABLE.html

5. W3Schools. (n.d.). SQL Indexes. Retrieved from https://www.w3schools.com/sql/sql_autoincrement.asp

Comments

Popular posts from this blog

SQL Triggers, Views & Materialized Views: Build Automated Audit Systems

Database Administration Guide: Backup, Recovery, Monitoring & Access Control

SQL Transactions Explained: ACID Properties, Deadlocks & Locking