Tạo Tables với DDL (Data Definition Language)
1. DDL Overview
DDL (Data Definition Language) là tập hợp các commands để định nghĩa database structure.
DDL Commands
DDL Commands
CREATE
DATABASE
SCHEMA
TABLE
INDEX
VIEW
ALTER
ADD column
ALTER column
DROP column
DROP
TABLE
DATABASE
TRUNCATE
Remove all rows
2. CREATE DATABASE & SCHEMA
2.1 Create Database
SQL
1-- Basic create database2CREATE DATABASE OnlineStore;3GO45-- With options6CREATE DATABASE OnlineStore7ON PRIMARY (8 NAME = 'OnlineStore_Data',9 FILENAME = 'C:\SQLData\OnlineStore_Data.mdf',10 SIZE = 100MB,11 MAXSIZE = 1GB,12 FILEGROWTH = 10%13)14LOG ON (15 NAME = 'OnlineStore_Log',16 FILENAME = 'C:\SQLData\OnlineStore_Log.ldf',17 SIZE = 50MB,18 MAXSIZE = 500MB,19 FILEGROWTH = 10%20);21GO2223-- Use database24USE OnlineStore;25GO2.2 Create Schema
SQL
1-- Schema giúp tổ chức tables theo modules2-- AdventureWorks có: Sales, Production, HumanResources, Person, Purchasing34-- Create schemas5CREATE SCHEMA Sales;6GO78CREATE SCHEMA Inventory;9GO1011CREATE SCHEMA Customer;12GO1314-- Xem schemas trong AdventureWorks15SELECT DISTINCT 16 SCHEMA_NAME(schema_id) AS SchemaName17FROM sys.tables18ORDER BY SchemaName;3. CREATE TABLE - Basic Syntax
3.1 Basic CREATE TABLE
SQL
1-- Syntax2CREATE TABLE SchemaName.TableName (3 Column1 DataType [Constraints],4 Column2 DataType [Constraints],5 ...6 [Table-level Constraints]7);89-- Example: Simple table10CREATE TABLE Customer.Customer (11 CustomerID INT IDENTITY(1,1) PRIMARY KEY,12 FirstName NVARCHAR(50) NOT NULL,13 LastName NVARCHAR(50) NOT NULL,14 Email VARCHAR(100) NOT NULL UNIQUE,15 Phone VARCHAR(20),16 CreatedDate DATETIME2 DEFAULT SYSDATETIME()17);3.2 IDENTITY Column
SQL
1-- IDENTITY(seed, increment)2CREATE TABLE Product (3 ProductID INT IDENTITY(1,1) PRIMARY KEY, -- Starts at 1, increments by 14 ProductName NVARCHAR(100)5);67-- Start at 1000, increment by 108CREATE TABLE Order (9 OrderID INT IDENTITY(1000, 10) PRIMARY KEY, -- 1000, 1010, 1020...10 OrderDate DATE11);1213-- Insert và lấy ID mới14INSERT INTO Product (ProductName) VALUES ('Laptop');15SELECT SCOPE_IDENTITY() AS NewProductID;1617-- Xem giá trị IDENTITY hiện tại18SELECT IDENT_CURRENT('Product') AS CurrentIdentity;1920-- Reset IDENTITY21DBCC CHECKIDENT ('Product', RESEED, 0);4. Complete Table Examples
4.1 E-commerce Database Schema
SQL
1-- 1. Category Table2CREATE TABLE Inventory.Category (3 CategoryID INT IDENTITY(1,1),4 CategoryName NVARCHAR(50) NOT NULL,5 Description NVARCHAR(500),6 ParentCategoryID INT,7 IsActive BIT NOT NULL DEFAULT 1,8 SortOrder SMALLINT DEFAULT 0,9 CreatedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),10 ModifiedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),11 12 -- Constraints13 CONSTRAINT PK_Category PRIMARY KEY (CategoryID),14 CONSTRAINT UQ_Category_Name UNIQUE (CategoryName),15 CONSTRAINT FK_Category_Parent FOREIGN KEY (ParentCategoryID) 16 REFERENCES Inventory.Category(CategoryID),17 CONSTRAINT CK_Category_SortOrder CHECK (SortOrder >= 0)18);19GO2021-- 2. Product Table22CREATE TABLE Inventory.Product (23 ProductID INT IDENTITY(1,1),24 SKU VARCHAR(20) NOT NULL,25 ProductName NVARCHAR(200) NOT NULL,26 Description NVARCHAR(MAX),27 CategoryID INT NOT NULL,28 UnitPrice DECIMAL(19, 4) NOT NULL,29 CostPrice DECIMAL(19, 4),30 StockQuantity INT NOT NULL DEFAULT 0,31 ReorderLevel INT DEFAULT 10,32 Weight DECIMAL(10, 2),33 ImageURL VARCHAR(500),34 IsActive BIT NOT NULL DEFAULT 1,35 CreatedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),36 ModifiedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),37 38 -- Constraints39 CONSTRAINT PK_Product PRIMARY KEY (ProductID),40 CONSTRAINT UQ_Product_SKU UNIQUE (SKU),41 CONSTRAINT FK_Product_Category FOREIGN KEY (CategoryID) 42 REFERENCES Inventory.Category(CategoryID),43 CONSTRAINT CK_Product_UnitPrice CHECK (UnitPrice >= 0),44 CONSTRAINT CK_Product_CostPrice CHECK (CostPrice >= 0),45 CONSTRAINT CK_Product_Stock CHECK (StockQuantity >= 0)46);47GO4849-- 3. Customer Table50CREATE TABLE Customer.Customer (51 CustomerID INT IDENTITY(1,1),52 Email VARCHAR(100) NOT NULL,53 PasswordHash VARBINARY(256) NOT NULL,54 FirstName NVARCHAR(50) NOT NULL,55 LastName NVARCHAR(50) NOT NULL,56 Phone VARCHAR(20),57 DateOfBirth DATE,58 Gender CHAR(1),59 IsEmailVerified BIT NOT NULL DEFAULT 0,60 IsActive BIT NOT NULL DEFAULT 1,61 LastLoginDate DATETIME2,62 CreatedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),63 ModifiedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),64 65 -- Constraints66 CONSTRAINT PK_Customer PRIMARY KEY (CustomerID),67 CONSTRAINT UQ_Customer_Email UNIQUE (Email),68 CONSTRAINT CK_Customer_Email CHECK (Email LIKE '%@%.%'),69 CONSTRAINT CK_Customer_Gender CHECK (Gender IN ('M', 'F', 'O'))70);71GO7273-- 4. Address Table (1:N with Customer)74CREATE TABLE Customer.Address (75 AddressID INT IDENTITY(1,1),76 CustomerID INT NOT NULL,77 AddressType VARCHAR(20) NOT NULL DEFAULT 'Shipping',78 AddressLine1 NVARCHAR(200) NOT NULL,79 AddressLine2 NVARCHAR(200),80 City NVARCHAR(100) NOT NULL,81 Province NVARCHAR(100) NOT NULL,82 PostalCode VARCHAR(10),83 Country NVARCHAR(50) NOT NULL DEFAULT N'Việt Nam',84 IsDefault BIT NOT NULL DEFAULT 0,85 CreatedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),86 87 CONSTRAINT PK_Address PRIMARY KEY (AddressID),88 CONSTRAINT FK_Address_Customer FOREIGN KEY (CustomerID) 89 REFERENCES Customer.Customer(CustomerID) ON DELETE CASCADE,90 CONSTRAINT CK_Address_Type CHECK (AddressType IN ('Shipping', 'Billing'))91);92GO9394-- 5. Order Table95CREATE TABLE Sales.[Order] ( -- Order là reserved word, cần []96 OrderID INT IDENTITY(1,1),97 OrderNumber VARCHAR(20) NOT NULL,98 CustomerID INT NOT NULL,99 OrderDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),100 Status VARCHAR(20) NOT NULL DEFAULT 'Pending',101 ShippingAddressID INT,102 BillingAddressID INT,103 SubTotal DECIMAL(19, 4) NOT NULL DEFAULT 0,104 ShippingFee DECIMAL(19, 4) NOT NULL DEFAULT 0,105 TaxAmount DECIMAL(19, 4) NOT NULL DEFAULT 0,106 DiscountAmount DECIMAL(19, 4) NOT NULL DEFAULT 0,107 TotalAmount AS (SubTotal + ShippingFee + TaxAmount - DiscountAmount) PERSISTED,108 Notes NVARCHAR(500),109 CreatedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),110 ModifiedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),111 112 CONSTRAINT PK_Order PRIMARY KEY (OrderID),113 CONSTRAINT UQ_Order_Number UNIQUE (OrderNumber),114 CONSTRAINT FK_Order_Customer FOREIGN KEY (CustomerID) 115 REFERENCES Customer.Customer(CustomerID),116 CONSTRAINT FK_Order_ShippingAddress FOREIGN KEY (ShippingAddressID) 117 REFERENCES Customer.Address(AddressID),118 CONSTRAINT FK_Order_BillingAddress FOREIGN KEY (BillingAddressID) 119 REFERENCES Customer.Address(AddressID),120 CONSTRAINT CK_Order_Status CHECK (Status IN ('Pending', 'Confirmed', 'Processing', 'Shipped', 'Delivered', 'Cancelled', 'Refunded')),121 CONSTRAINT CK_Order_SubTotal CHECK (SubTotal >= 0)122);123GO124125-- 6. OrderDetail Table126CREATE TABLE Sales.OrderDetail (127 OrderDetailID INT IDENTITY(1,1),128 OrderID INT NOT NULL,129 ProductID INT NOT NULL,130 Quantity INT NOT NULL,131 UnitPrice DECIMAL(19, 4) NOT NULL,132 Discount DECIMAL(4, 2) NOT NULL DEFAULT 0,133 LineTotal AS (Quantity * UnitPrice * (1 - Discount)) PERSISTED,134 135 CONSTRAINT PK_OrderDetail PRIMARY KEY (OrderDetailID),136 CONSTRAINT FK_OrderDetail_Order FOREIGN KEY (OrderID) 137 REFERENCES Sales.[Order](OrderID) ON DELETE CASCADE,138 CONSTRAINT FK_OrderDetail_Product FOREIGN KEY (ProductID) 139 REFERENCES Inventory.Product(ProductID),140 CONSTRAINT CK_OrderDetail_Quantity CHECK (Quantity > 0),141 CONSTRAINT CK_OrderDetail_UnitPrice CHECK (UnitPrice >= 0),142 CONSTRAINT CK_OrderDetail_Discount CHECK (Discount >= 0 AND Discount <= 1)143);144GO4.2 Create Indexes
SQL
1-- Indexes cho performance (chi tiết ở bài Indexing)2CREATE INDEX IX_Product_CategoryID ON Inventory.Product(CategoryID);3CREATE INDEX IX_Order_CustomerID ON Sales.[Order](CustomerID);4CREATE INDEX IX_Order_OrderDate ON Sales.[Order](OrderDate DESC);5CREATE INDEX IX_OrderDetail_OrderID ON Sales.OrderDetail(OrderID);6CREATE INDEX IX_Customer_Email ON Customer.Customer(Email);5. ALTER TABLE
5.1 Add Column
SQL
1-- Add single column2ALTER TABLE Customer.Customer3ADD MiddleName NVARCHAR(50);45-- Add multiple columns6ALTER TABLE Customer.Customer7ADD 8 ReferralCode VARCHAR(20),9 ReferredBy INT;1011-- Add with constraint12ALTER TABLE Customer.Customer13ADD LoyaltyPoints INT NOT NULL DEFAULT 014 CONSTRAINT CK_Customer_LoyaltyPoints CHECK (LoyaltyPoints >= 0);5.2 Modify Column
SQL
1-- Change data type (careful với existing data!)2ALTER TABLE Customer.Customer3ALTER COLUMN Phone VARCHAR(30);45-- Change to NOT NULL (phải không có NULL values)6UPDATE Customer.Customer SET MiddleName = '' WHERE MiddleName IS NULL;7ALTER TABLE Customer.Customer8ALTER COLUMN MiddleName NVARCHAR(50) NOT NULL;910-- Change size11ALTER TABLE Inventory.Product12ALTER COLUMN Description NVARCHAR(2000);5.3 Drop Column
SQL
1-- Drop column2ALTER TABLE Customer.Customer3DROP COLUMN MiddleName;45-- Drop column với constraint6-- Phải drop constraint trước7ALTER TABLE Customer.Customer8DROP CONSTRAINT CK_Customer_LoyaltyPoints;910ALTER TABLE Customer.Customer11DROP COLUMN LoyaltyPoints;5.4 Add/Drop Constraints
SQL
1-- Add constraint2ALTER TABLE Inventory.Product3ADD CONSTRAINT CK_Product_Weight CHECK (Weight > 0);45-- Add foreign key6ALTER TABLE Customer.Customer7ADD CONSTRAINT FK_Customer_ReferredBy 8 FOREIGN KEY (ReferredBy) REFERENCES Customer.Customer(CustomerID);910-- Drop constraint11ALTER TABLE Inventory.Product12DROP CONSTRAINT CK_Product_Weight;6. DROP & TRUNCATE
6.1 DROP TABLE
SQL
1-- Drop table (careful!)2DROP TABLE Sales.OrderDetail;3DROP TABLE Sales.[Order];45-- Drop if exists (SQL Server 2016+)6DROP TABLE IF EXISTS Sales.OrderDetail;7DROP TABLE IF EXISTS Sales.[Order];89-- Drop with dependencies check10-- Must drop in correct order due to FK constraints!11-- 1. OrderDetail first (references Order)12-- 2. Order next (references Customer, Address)13-- 3. Address, Customer last1415-- Hoặc disable FKs temporarily16EXEC sp_MSforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL';17-- Drop tables18EXEC sp_MSforeachtable 'ALTER TABLE ? CHECK CONSTRAINT ALL';6.2 TRUNCATE vs DELETE
SQL
1-- TRUNCATE - Remove all rows, reset IDENTITY2TRUNCATE TABLE Sales.TempLog;34-- DELETE - Remove all rows, keep IDENTITY5DELETE FROM Sales.TempLog;67-- TRUNCATE với FK (không được!)8-- Error: Cannot truncate table because it is being referenced by FK9-- Phải disable FK hoặc dùng DELETE| Feature | TRUNCATE | DELETE |
|---|---|---|
| Speed | Faster (minimal logging) | Slower |
| IDENTITY | Resets | Keeps |
| WHERE clause | No | Yes |
| Trigger | No | Yes |
| FK check | Cannot with FK | Can with FK |
| Rollback | Yes | Yes |
7. Best Practices
7.1 Naming Conventions
SQL
1-- Table names: PascalCase, singular2CREATE TABLE Customer (...); -- ✅3CREATE TABLE Customers (...); -- ❌ Avoid plural4CREATE TABLE customer (...); -- ❌ Avoid lowercase56-- Column names: PascalCase7CustomerID, FirstName, CreatedDate89-- Constraint names: Type_Table_Column10PK_Customer -- Primary Key11FK_Order_Customer -- Foreign Key12UQ_Customer_Email -- Unique13CK_Product_Price -- Check14DF_Order_Status -- Default15IX_Order_CustomerID -- Index7.2 Standard Columns
SQL
1-- Audit columns (add to every table)2CREATE TABLE MyTable (3 -- Business columns4 ...5 6 -- Audit columns7 CreatedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),8 CreatedBy NVARCHAR(100) DEFAULT SYSTEM_USER,9 ModifiedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),10 ModifiedBy NVARCHAR(100) DEFAULT SYSTEM_USER,11 12 -- Soft delete (optional)13 IsDeleted BIT NOT NULL DEFAULT 0,14 DeletedDate DATETIME215);7.3 Table Template
SQL
1-- Standard table template2CREATE TABLE SchemaName.TableName (3 -- Primary Key4 TableNameID INT IDENTITY(1,1),5 6 -- Business columns7 Column1 DataType NOT NULL,8 Column2 DataType,9 10 -- Foreign Keys11 RelatedTableID INT NOT NULL,12 13 -- Status/Flag columns14 IsActive BIT NOT NULL DEFAULT 1,15 16 -- Audit columns17 CreatedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),18 ModifiedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),19 20 -- Constraints21 CONSTRAINT PK_TableName PRIMARY KEY (TableNameID),22 CONSTRAINT FK_TableName_RelatedTable FOREIGN KEY (RelatedTableID) 23 REFERENCES SchemaName.RelatedTable(RelatedTableID)24);25GO2627-- Index for FK28CREATE INDEX IX_TableName_RelatedTableID ON SchemaName.TableName(RelatedTableID);29GO8. Hands-on Exercise
Exercise: Design Blog Database
Tạo database cho Blog system với requirements:
- Users có thể tạo nhiều Posts
- Posts có Categories (M:N)
- Posts có Comments từ Users
- Posts có Tags (M:N)
SQL
1-- Your solution here2-- 1. Create Schema3CREATE SCHEMA Blog;4GO56-- 2. Create User table7CREATE TABLE Blog.[User] (8 UserID INT IDENTITY(1,1),9 Username VARCHAR(50) NOT NULL,10 Email VARCHAR(100) NOT NULL,11 PasswordHash VARBINARY(256) NOT NULL,12 DisplayName NVARCHAR(100),13 Avatar VARCHAR(500),14 Bio NVARCHAR(1000),15 IsActive BIT NOT NULL DEFAULT 1,16 CreatedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),17 18 CONSTRAINT PK_User PRIMARY KEY (UserID),19 CONSTRAINT UQ_User_Username UNIQUE (Username),20 CONSTRAINT UQ_User_Email UNIQUE (Email)21);2223-- 3. Create Category table24CREATE TABLE Blog.Category (25 CategoryID INT IDENTITY(1,1),26 CategoryName NVARCHAR(50) NOT NULL,27 Slug VARCHAR(50) NOT NULL,28 Description NVARCHAR(500),29 30 CONSTRAINT PK_Category PRIMARY KEY (CategoryID),31 CONSTRAINT UQ_Category_Slug UNIQUE (Slug)32);3334-- 4. Create Tag table35CREATE TABLE Blog.Tag (36 TagID INT IDENTITY(1,1),37 TagName NVARCHAR(30) NOT NULL,38 Slug VARCHAR(30) NOT NULL,39 40 CONSTRAINT PK_Tag PRIMARY KEY (TagID),41 CONSTRAINT UQ_Tag_Slug UNIQUE (Slug)42);4344-- 5. Create Post table45CREATE TABLE Blog.Post (46 PostID INT IDENTITY(1,1),47 Title NVARCHAR(200) NOT NULL,48 Slug VARCHAR(200) NOT NULL,49 Content NVARCHAR(MAX) NOT NULL,50 Excerpt NVARCHAR(500),51 AuthorID INT NOT NULL,52 Status VARCHAR(20) NOT NULL DEFAULT 'Draft',53 ViewCount INT NOT NULL DEFAULT 0,54 PublishedDate DATETIME2,55 CreatedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),56 ModifiedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),57 58 CONSTRAINT PK_Post PRIMARY KEY (PostID),59 CONSTRAINT UQ_Post_Slug UNIQUE (Slug),60 CONSTRAINT FK_Post_Author FOREIGN KEY (AuthorID) 61 REFERENCES Blog.[User](UserID),62 CONSTRAINT CK_Post_Status CHECK (Status IN ('Draft', 'Published', 'Archived'))63);6465-- 6. Junction: Post_Category (M:N)66CREATE TABLE Blog.PostCategory (67 PostID INT NOT NULL,68 CategoryID INT NOT NULL,69 70 CONSTRAINT PK_PostCategory PRIMARY KEY (PostID, CategoryID),71 CONSTRAINT FK_PostCategory_Post FOREIGN KEY (PostID) 72 REFERENCES Blog.Post(PostID) ON DELETE CASCADE,73 CONSTRAINT FK_PostCategory_Category FOREIGN KEY (CategoryID) 74 REFERENCES Blog.Category(CategoryID) ON DELETE CASCADE75);7677-- 7. Junction: Post_Tag (M:N)78CREATE TABLE Blog.PostTag (79 PostID INT NOT NULL,80 TagID INT NOT NULL,81 82 CONSTRAINT PK_PostTag PRIMARY KEY (PostID, TagID),83 CONSTRAINT FK_PostTag_Post FOREIGN KEY (PostID) 84 REFERENCES Blog.Post(PostID) ON DELETE CASCADE,85 CONSTRAINT FK_PostTag_Tag FOREIGN KEY (TagID) 86 REFERENCES Blog.Tag(TagID) ON DELETE CASCADE87);8889-- 8. Comment table90CREATE TABLE Blog.Comment (91 CommentID INT IDENTITY(1,1),92 PostID INT NOT NULL,93 UserID INT NOT NULL,94 ParentCommentID INT, -- For replies95 Content NVARCHAR(2000) NOT NULL,96 IsApproved BIT NOT NULL DEFAULT 0,97 CreatedDate DATETIME2 NOT NULL DEFAULT SYSDATETIME(),98 99 CONSTRAINT PK_Comment PRIMARY KEY (CommentID),100 CONSTRAINT FK_Comment_Post FOREIGN KEY (PostID) 101 REFERENCES Blog.Post(PostID) ON DELETE CASCADE,102 CONSTRAINT FK_Comment_User FOREIGN KEY (UserID) 103 REFERENCES Blog.[User](UserID),104 CONSTRAINT FK_Comment_Parent FOREIGN KEY (ParentCommentID) 105 REFERENCES Blog.Comment(CommentID)106);107GO108109-- Create indexes110CREATE INDEX IX_Post_AuthorID ON Blog.Post(AuthorID);111CREATE INDEX IX_Post_Status ON Blog.Post(Status);112CREATE INDEX IX_Comment_PostID ON Blog.Comment(PostID);113GOTiếp theo
Bài tiếp theo: Views trong SQL Server - học cách tạo và sử dụng Views để đơn giản hóa queries!
