DDL数据定义语言

# DDL数据定义语言

# 概述

DDL(Data Definition Language,数据定义语言)是SQL的一个子集,用于定义和管理数据库结构。DDL语句主要用于创建、修改和删除数据库对象,如数据库、表、索引、视图等。

# 主要DDL语句

# 1. CREATE - 创建对象

# 创建数据库

-- 基本语法
CREATE DATABASE database_name;

-- 指定字符集和排序规则
CREATE DATABASE ecommerce 
CHARACTER SET utf8mb4 
COLLATE utf8mb4_unicode_ci;

-- MySQL示例
CREATE DATABASE IF NOT EXISTS shop
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;

-- SQL Server示例
CREATE DATABASE CompanyDB
ON (NAME = 'CompanyDB_Data',
    FILENAME = 'C:\Data\CompanyDB.mdf',
    SIZE = 100MB,
    MAXSIZE = 1GB,
    FILEGROWTH = 10MB)
LOG ON (NAME = 'CompanyDB_Log',
        FILENAME = 'C:\Data\CompanyDB.ldf',
        SIZE = 10MB,
        FILEGROWTH = 10%);

# 创建表

-- 基本表创建
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- 复杂表创建示例
CREATE TABLE orders (
    order_id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT NOT NULL,
    order_number VARCHAR(20) NOT NULL UNIQUE,
    total_amount DECIMAL(10,2) NOT NULL DEFAULT 0.00,
    status ENUM('pending', 'paid', 'shipped', 'delivered', 'cancelled') DEFAULT 'pending',
    order_date DATETIME DEFAULT CURRENT_TIMESTAMP,
    shipping_address TEXT,
    
    -- 外键约束
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
    
    -- 检查约束
    CHECK (total_amount >= 0),
    
    -- 索引
    INDEX idx_user_id (user_id),
    INDEX idx_order_date (order_date),
    INDEX idx_status (status)
);

-- 从其他表创建表
CREATE TABLE users_backup AS SELECT * FROM users;

-- 创建临时表
CREATE TEMPORARY TABLE temp_sales (
    product_id INT,
    sales_amount DECIMAL(10,2),
    sale_date DATE
);

# 创建索引

-- 普通索引
CREATE INDEX idx_username ON users(username);

-- 唯一索引
CREATE UNIQUE INDEX idx_email ON users(email);

-- 复合索引
CREATE INDEX idx_user_date ON orders(user_id, order_date);

-- 部分索引(PostgreSQL)
CREATE INDEX idx_active_users ON users(username) WHERE status = 'active';

-- 函数索引
CREATE INDEX idx_upper_username ON users(UPPER(username));

# 创建视图

-- 简单视图
CREATE VIEW active_users AS
SELECT id, username, email, created_at
FROM users
WHERE status = 'active';

-- 复杂视图
CREATE VIEW order_summary AS
SELECT 
    u.username,
    u.email,
    COUNT(o.order_id) as total_orders,
    SUM(o.total_amount) as total_spent,
    MAX(o.order_date) as last_order_date
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id, u.username, u.email;

-- 可更新视图
CREATE VIEW user_profiles AS
SELECT id, username, email, first_name, last_name
FROM users
WHERE status = 'active'
WITH CHECK OPTION;

# 2. ALTER - 修改对象

# 修改表结构

-- 添加列
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
ALTER TABLE users ADD COLUMN (age INT, gender ENUM('M', 'F'));

-- 修改列
ALTER TABLE users MODIFY COLUMN phone VARCHAR(15) NOT NULL;
ALTER TABLE users CHANGE COLUMN phone mobile VARCHAR(15);

-- 删除列
ALTER TABLE users DROP COLUMN age;

-- 添加约束
ALTER TABLE users ADD CONSTRAINT uk_email UNIQUE (email);
ALTER TABLE orders ADD CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id);
ALTER TABLE products ADD CONSTRAINT chk_price CHECK (price > 0);

-- 删除约束
ALTER TABLE users DROP CONSTRAINT uk_email;
ALTER TABLE orders DROP FOREIGN KEY fk_user;

-- 重命名表
ALTER TABLE users RENAME TO customers;

-- 修改表选项
ALTER TABLE users ENGINE=InnoDB;
ALTER TABLE users CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

# 修改索引

-- 重命名索引
ALTER TABLE users RENAME INDEX old_index_name TO new_index_name;

-- 修改索引(通常需要删除后重建)
DROP INDEX idx_username ON users;
CREATE INDEX idx_username_email ON users(username, email);

# 3. DROP - 删除对象

# 删除数据库

-- 删除数据库
DROP DATABASE IF EXISTS old_database;

-- 强制删除(SQL Server)
ALTER DATABASE old_database SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE old_database;

# 删除表

-- 删除表
DROP TABLE IF EXISTS temp_table;

-- 删除多个表
DROP TABLE table1, table2, table3;

-- 级联删除(删除依赖对象)
DROP TABLE users CASCADE;

# 删除索引

-- MySQL
DROP INDEX idx_username ON users;

-- SQL Server
DROP INDEX users.idx_username;

-- PostgreSQL
DROP INDEX idx_username;

# 删除视图

DROP VIEW IF EXISTS order_summary;

# 4. TRUNCATE - 清空表

-- 清空表数据(保留表结构)
TRUNCATE TABLE logs;

-- 重置自增ID
TRUNCATE TABLE users; -- 自动重置AUTO_INCREMENT

-- 注意:TRUNCATE比DELETE快,但不能回滚

# 约束类型详解

# 1. 主键约束(PRIMARY KEY)

-- 单列主键
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50)
);

-- 复合主键
CREATE TABLE order_items (
    order_id INT,
    product_id INT,
    quantity INT,
    PRIMARY KEY (order_id, product_id)
);

-- 添加主键约束
ALTER TABLE users ADD PRIMARY KEY (id);

-- 删除主键约束
ALTER TABLE users DROP PRIMARY KEY;

# 2. 外键约束(FOREIGN KEY)

-- 创建时定义外键
CREATE TABLE orders (
    id INT PRIMARY KEY,
    user_id INT,
    FOREIGN KEY (user_id) REFERENCES users(id)
        ON DELETE CASCADE
        ON UPDATE RESTRICT
);

-- 添加外键约束
ALTER TABLE orders 
ADD CONSTRAINT fk_orders_user 
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE SET NULL
ON UPDATE CASCADE;

-- 删除外键约束
ALTER TABLE orders DROP FOREIGN KEY fk_orders_user;

# 3. 唯一约束(UNIQUE)

-- 单列唯一
CREATE TABLE users (
    id INT PRIMARY KEY,
    email VARCHAR(100) UNIQUE
);

-- 复合唯一
CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    category_id INT,
    UNIQUE KEY uk_name_category (name, category_id)
);

-- 添加唯一约束
ALTER TABLE users ADD CONSTRAINT uk_username UNIQUE (username);

# 4. 检查约束(CHECK)

-- 简单检查约束
CREATE TABLE products (
    id INT PRIMARY KEY,
    price DECIMAL(10,2) CHECK (price > 0),
    stock INT CHECK (stock >= 0)
);

-- 复杂检查约束
CREATE TABLE employees (
    id INT PRIMARY KEY,
    birth_date DATE,
    hire_date DATE,
    salary DECIMAL(10,2),
    CHECK (hire_date > birth_date),
    CHECK (salary BETWEEN 1000 AND 100000)
);

-- 添加检查约束
ALTER TABLE products 
ADD CONSTRAINT chk_price_positive 
CHECK (price > 0);

# 5. 非空约束(NOT NULL)

-- 创建时定义
CREATE TABLE users (
    id INT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL
);

-- 修改为非空
ALTER TABLE users MODIFY COLUMN phone VARCHAR(20) NOT NULL;

-- 移除非空约束
ALTER TABLE users MODIFY COLUMN phone VARCHAR(20) NULL;

# 数据类型详解

# 1. 数值类型

CREATE TABLE numeric_examples (
    -- 整数类型
    tiny_int TINYINT,           -- 1字节,-128到127
    small_int SMALLINT,         -- 2字节,-32768到32767
    medium_int MEDIUMINT,       -- 3字节,-8388608到8388607
    normal_int INT,             -- 4字节,-2147483648到2147483647
    big_int BIGINT,             -- 8字节
    
    -- 无符号整数
    unsigned_int INT UNSIGNED,  -- 0到4294967295
    
    -- 自增
    auto_id INT AUTO_INCREMENT PRIMARY KEY,
    
    -- 小数类型
    float_num FLOAT(7,4),       -- 单精度浮点
    double_num DOUBLE(15,8),    -- 双精度浮点
    decimal_num DECIMAL(10,2),  -- 精确小数
    
    -- 布尔类型
    is_active BOOLEAN           -- 等同于TINYINT(1)
);

# 2. 字符串类型

CREATE TABLE string_examples (
    -- 定长字符串
    char_field CHAR(10),        -- 固定长度,不足补空格
    
    -- 变长字符串
    varchar_field VARCHAR(255), -- 可变长度
    
    -- 文本类型
    tiny_text TINYTEXT,         -- 最大255字符
    normal_text TEXT,           -- 最大65535字符
    medium_text MEDIUMTEXT,     -- 最大16777215字符
    long_text LONGTEXT,         -- 最大4294967295字符
    
    -- 二进制类型
    binary_field BINARY(16),    -- 固定长度二进制
    varbinary_field VARBINARY(255), -- 可变长度二进制
    blob_field BLOB,            -- 二进制大对象
    
    -- 枚举和集合
    status ENUM('active', 'inactive', 'pending'),
    permissions SET('read', 'write', 'execute')
);

# 3. 日期时间类型

CREATE TABLE datetime_examples (
    -- 日期类型
    date_field DATE,            -- YYYY-MM-DD
    
    -- 时间类型
    time_field TIME,            -- HH:MM:SS
    
    -- 日期时间类型
    datetime_field DATETIME,    -- YYYY-MM-DD HH:MM:SS
    timestamp_field TIMESTAMP,  -- 自动更新的时间戳
    
    -- 年份
    year_field YEAR,            -- YYYY
    
    -- 默认值示例
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

# 实战案例

# 案例1:电商系统数据库设计

-- 创建数据库
CREATE DATABASE ecommerce CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE ecommerce;

-- 用户表
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    password_hash VARCHAR(255) NOT NULL,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    phone VARCHAR(20),
    birth_date DATE,
    gender ENUM('M', 'F', 'Other'),
    status ENUM('active', 'inactive', 'suspended') DEFAULT 'active',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    
    INDEX idx_email (email),
    INDEX idx_status (status),
    INDEX idx_created_at (created_at)
);

-- 商品分类表
CREATE TABLE categories (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    description TEXT,
    parent_id INT,
    sort_order INT DEFAULT 0,
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    FOREIGN KEY (parent_id) REFERENCES categories(id) ON DELETE SET NULL,
    INDEX idx_parent_id (parent_id),
    INDEX idx_sort_order (sort_order)
);

-- 商品表
CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(200) NOT NULL,
    description TEXT,
    category_id INT NOT NULL,
    sku VARCHAR(50) NOT NULL UNIQUE,
    price DECIMAL(10,2) NOT NULL,
    cost_price DECIMAL(10,2),
    stock INT NOT NULL DEFAULT 0,
    min_stock INT DEFAULT 0,
    weight DECIMAL(8,3),
    dimensions VARCHAR(50),
    status ENUM('active', 'inactive', 'discontinued') DEFAULT 'active',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    
    FOREIGN KEY (category_id) REFERENCES categories(id),
    CHECK (price > 0),
    CHECK (stock >= 0),
    CHECK (cost_price >= 0),
    
    INDEX idx_category_id (category_id),
    INDEX idx_sku (sku),
    INDEX idx_price (price),
    INDEX idx_status (status),
    FULLTEXT idx_name_description (name, description)
);

-- 订单表
CREATE TABLE orders (
    id INT PRIMARY KEY AUTO_INCREMENT,
    order_number VARCHAR(20) NOT NULL UNIQUE,
    user_id INT NOT NULL,
    status ENUM('pending', 'paid', 'processing', 'shipped', 'delivered', 'cancelled') DEFAULT 'pending',
    subtotal DECIMAL(10,2) NOT NULL DEFAULT 0,
    tax_amount DECIMAL(10,2) NOT NULL DEFAULT 0,
    shipping_amount DECIMAL(10,2) NOT NULL DEFAULT 0,
    total_amount DECIMAL(10,2) NOT NULL DEFAULT 0,
    currency CHAR(3) DEFAULT 'USD',
    payment_method VARCHAR(50),
    payment_status ENUM('pending', 'paid', 'failed', 'refunded') DEFAULT 'pending',
    shipping_address TEXT,
    billing_address TEXT,
    notes TEXT,
    order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    shipped_date TIMESTAMP NULL,
    delivered_date TIMESTAMP NULL,
    
    FOREIGN KEY (user_id) REFERENCES users(id),
    CHECK (subtotal >= 0),
    CHECK (tax_amount >= 0),
    CHECK (shipping_amount >= 0),
    CHECK (total_amount >= 0),
    
    INDEX idx_user_id (user_id),
    INDEX idx_order_number (order_number),
    INDEX idx_status (status),
    INDEX idx_order_date (order_date),
    INDEX idx_payment_status (payment_status)
);

-- 订单项表
CREATE TABLE order_items (
    id INT PRIMARY KEY AUTO_INCREMENT,
    order_id INT NOT NULL,
    product_id INT NOT NULL,
    quantity INT NOT NULL,
    unit_price DECIMAL(10,2) NOT NULL,
    total_price DECIMAL(10,2) NOT NULL,
    
    FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE,
    FOREIGN KEY (product_id) REFERENCES products(id),
    CHECK (quantity > 0),
    CHECK (unit_price > 0),
    CHECK (total_price > 0),
    
    UNIQUE KEY uk_order_product (order_id, product_id),
    INDEX idx_product_id (product_id)
);

# 案例2:博客系统数据库设计

-- 创建博客数据库
CREATE DATABASE blog_system CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE blog_system;

-- 作者表
CREATE TABLE authors (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    display_name VARCHAR(100),
    bio TEXT,
    avatar_url VARCHAR(255),
    website_url VARCHAR(255),
    social_links JSON,
    is_verified BOOLEAN DEFAULT FALSE,
    status ENUM('active', 'inactive', 'banned') DEFAULT 'active',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    last_login_at TIMESTAMP NULL,
    
    INDEX idx_username (username),
    INDEX idx_email (email),
    INDEX idx_status (status)
);

-- 文章分类表
CREATE TABLE categories (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL UNIQUE,
    slug VARCHAR(100) NOT NULL UNIQUE,
    description TEXT,
    color VARCHAR(7), -- 十六进制颜色代码
    sort_order INT DEFAULT 0,
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    INDEX idx_slug (slug),
    INDEX idx_sort_order (sort_order)
);

-- 标签表
CREATE TABLE tags (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL UNIQUE,
    slug VARCHAR(50) NOT NULL UNIQUE,
    description TEXT,
    usage_count INT DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    INDEX idx_slug (slug),
    INDEX idx_usage_count (usage_count)
);

-- 文章表
CREATE TABLE articles (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(200) NOT NULL,
    slug VARCHAR(200) NOT NULL,
    excerpt TEXT,
    content LONGTEXT NOT NULL,
    author_id INT NOT NULL,
    category_id INT,
    featured_image VARCHAR(255),
    status ENUM('draft', 'published', 'archived') DEFAULT 'draft',
    is_featured BOOLEAN DEFAULT FALSE,
    view_count INT DEFAULT 0,
    like_count INT DEFAULT 0,
    comment_count INT DEFAULT 0,
    reading_time INT, -- 预估阅读时间(分钟)
    seo_title VARCHAR(200),
    seo_description TEXT,
    published_at TIMESTAMP NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    
    FOREIGN KEY (author_id) REFERENCES authors(id),
    FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE SET NULL,
    
    UNIQUE KEY uk_slug_published (slug, published_at),
    INDEX idx_author_id (author_id),
    INDEX idx_category_id (category_id),
    INDEX idx_status (status),
    INDEX idx_published_at (published_at),
    INDEX idx_is_featured (is_featured),
    FULLTEXT idx_title_content (title, content)
);

-- 文章标签关联表
CREATE TABLE article_tags (
    article_id INT NOT NULL,
    tag_id INT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    PRIMARY KEY (article_id, tag_id),
    FOREIGN KEY (article_id) REFERENCES articles(id) ON DELETE CASCADE,
    FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE
);

# 性能优化建议

# 1. 表设计优化

-- 选择合适的数据类型
-- 好的做法
CREATE TABLE users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, -- 使用无符号整数
    status TINYINT UNSIGNED,                     -- 小范围数值用TINYINT
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 使用TIMESTAMP而不是DATETIME
);

-- 避免过长的VARCHAR
-- 不好的做法
email VARCHAR(1000) -- 过长
-- 好的做法
email VARCHAR(100)  -- 合适的长度

-- 使用适当的字符集
CREATE TABLE content (
    id INT PRIMARY KEY,
    title VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
);

# 2. 索引优化

-- 复合索引的列顺序很重要
-- 根据查询模式设计索引
CREATE INDEX idx_user_date_status ON orders(user_id, order_date, status);

-- 这个索引可以优化以下查询:
-- SELECT * FROM orders WHERE user_id = 123;
-- SELECT * FROM orders WHERE user_id = 123 AND order_date > '2024-01-01';
-- SELECT * FROM orders WHERE user_id = 123 AND order_date > '2024-01-01' AND status = 'paid';

-- 避免冗余索引
-- 如果已有复合索引(a, b, c),就不需要单独的索引(a)或(a, b)

# 3. 约束优化

-- 使用适当的外键约束
CREATE TABLE orders (
    id INT PRIMARY KEY,
    user_id INT NOT NULL,
    -- 根据业务需求选择合适的外键行为
    FOREIGN KEY (user_id) REFERENCES users(id) 
        ON DELETE RESTRICT  -- 防止删除有订单的用户
        ON UPDATE CASCADE   -- 用户ID更新时同步更新
);

-- 使用检查约束提高数据质量
CREATE TABLE products (
    id INT PRIMARY KEY,
    price DECIMAL(10,2) CHECK (price > 0),
    discount_rate DECIMAL(5,2) CHECK (discount_rate BETWEEN 0 AND 100)
);

# 常见错误和解决方案

# 1. 字符集问题

-- 问题:中文乱码
-- 解决方案:使用utf8mb4字符集
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

CREATE TABLE users (
    name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
);

# 2. 外键约束错误

-- 问题:Cannot add foreign key constraint
-- 原因:数据类型不匹配或引用的列不存在

-- 错误示例
CREATE TABLE orders (
    user_id VARCHAR(10), -- 类型不匹配
    FOREIGN KEY (user_id) REFERENCES users(id) -- users.id是INT类型
);

-- 正确示例
CREATE TABLE orders (
    user_id INT, -- 类型匹配
    FOREIGN KEY (user_id) REFERENCES users(id)
);

# 3. 索引长度限制

-- 问题:Specified key was too long
-- 解决方案:限制索引长度

-- 错误示例
CREATE INDEX idx_long_text ON articles(content); -- content是LONGTEXT

-- 正确示例
CREATE INDEX idx_content_prefix ON articles(content(100)); -- 只索引前100个字符
-- 或使用全文索引
CREATE FULLTEXT INDEX idx_content_fulltext ON articles(content);

# 最佳实践

# 1. 命名规范

-- 表名:使用复数形式,小写,下划线分隔
CREATE TABLE user_profiles;
CREATE TABLE order_items;

-- 列名:小写,下划线分隔,有意义的名称
CREATE TABLE users (
    id INT PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    email_address VARCHAR(100),
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);

-- 索引名:使用前缀标识类型
CREATE INDEX idx_users_email ON users(email_address);        -- 普通索引
CREATE UNIQUE INDEX uk_users_username ON users(username);    -- 唯一索引
CREATE INDEX fk_orders_user_id ON orders(user_id);          -- 外键索引

-- 约束名:使用前缀标识类型
ALTER TABLE orders ADD CONSTRAINT fk_orders_user_id FOREIGN KEY (user_id) REFERENCES users(id);
ALTER TABLE products ADD CONSTRAINT chk_products_price_positive CHECK (price > 0);

# 2. 安全性考虑

-- 使用适当的权限
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'strong_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON ecommerce.* TO 'app_user'@'localhost';

-- 避免使用root用户进行应用连接
-- 定期更换密码
-- 使用SSL连接

# 3. 备份和恢复考虑

-- 在重要操作前备份
-- 使用事务确保数据一致性
START TRANSACTION;

ALTER TABLE users ADD COLUMN new_field VARCHAR(100);
-- 验证更改
SELECT COUNT(*) FROM users;

COMMIT; -- 或 ROLLBACK; 如果有问题

# 总结

DDL是数据库设计和管理的基础,正确使用DDL语句可以:

  1. 创建高效的数据库结构:合理的表设计和索引策略
  2. 确保数据完整性:通过约束保证数据质量
  3. 提高查询性能:适当的索引和数据类型选择
  4. 便于维护管理:清晰的命名规范和文档

在实际开发中,建议先进行详细的需求分析和数据建模,然后编写DDL脚本,并在测试环境中充分验证后再应用到生产环境。