MySQL中唯一索引和主键的区别

MySQL中唯一索引和主键的区别

一、概述

1.1 基本概念

在MySQL数据库中,唯一索引(UNIQUE INDEX)和主键(PRIMARY KEY)都是用于保证数据唯一性的重要机制,但它们在功能、特性和使用场景上存在显著差异。

1.2 核心差异

特性 主键 唯一索引
唯一性 必须唯一 必须唯一
空值处理 不允许NULL 允许NULL(除非明确约束)
数量限制 每表只能有一个 每表可以有多个
自动创建 自动创建聚集索引 创建非聚集索引
外键引用 可以被外键引用 不能被外键引用
默认行为 自动递增(可选) 无自动递增

二、主键详解

2.1 主键特性

基本定义
-- 主键的基本特性
-- 1. 唯一性:主键值在表中必须唯一
-- 2. 非空性:主键字段不能为NULL
-- 3. 唯一性:每个表只能有一个主键
-- 4. 聚集索引:主键自动创建聚集索引

-- 创建带主键的表
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 查看表结构
DESCRIBE users;

-- 查看索引信息
SHOW INDEX FROM users;
主键约束
-- 主键约束示例
CREATE TABLE products (
    product_id INT,
    product_code VARCHAR(20),
    product_name VARCHAR(100),
    price DECIMAL(10,2),
    
    -- 单字段主键
    PRIMARY KEY (product_id)
);

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

-- 查看主键信息
SELECT 
    TABLE_NAME,
    COLUMN_NAME,
    CONSTRAINT_NAME,
    REFERENCED_TABLE_NAME,
    REFERENCED_COLUMN_NAME
FROM information_schema.KEY_COLUMN_USAGE 
WHERE TABLE_SCHEMA = 'mydb' 
AND CONSTRAINT_NAME = 'PRIMARY';

2.2 主键的自动递增

AUTO_INCREMENT特性
-- 自动递增主键
CREATE TABLE categories (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 插入数据(不指定id)
INSERT INTO categories (name, description) VALUES 
('电子产品', '各类电子产品'),
('服装鞋帽', '时尚服装和鞋帽'),
('家居用品', '家居生活用品');

-- 查看插入的数据
SELECT * FROM categories;

-- 查看AUTO_INCREMENT当前值
SHOW TABLE STATUS LIKE 'categories';

-- 重置AUTO_INCREMENT
ALTER TABLE categories AUTO_INCREMENT = 1;
自增主键的注意事项
-- 自增主键的间隙问题
CREATE TABLE test_auto_increment (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50)
);

-- 插入数据
INSERT INTO test_auto_increment (name) VALUES ('A'), ('B'), ('C');

-- 删除中间记录
DELETE FROM test_auto_increment WHERE id = 2;

-- 插入新记录(会使用id=4,而不是2)
INSERT INTO test_auto_increment (name) VALUES ('D');

-- 查看结果
SELECT * FROM test_auto_increment;

-- 手动指定自增值
INSERT INTO test_auto_increment (id, name) VALUES (2, 'E');

2.3 主键的聚集索引

聚集索引特性
-- 主键自动创建聚集索引
CREATE TABLE employees (
    employee_id INT PRIMARY KEY AUTO_INCREMENT,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    email VARCHAR(100),
    hire_date DATE
);

-- 查看索引信息
SHOW INDEX FROM employees;

-- 分析查询执行计划
EXPLAIN SELECT * FROM employees WHERE employee_id = 1;

-- 查看表的存储信息
SELECT 
    table_name,
    engine,
    table_rows,
    avg_row_length,
    data_length,
    index_length
FROM information_schema.tables 
WHERE table_schema = 'mydb' 
AND table_name = 'employees';

三、唯一索引详解

3.1 唯一索引特性

基本定义
-- 唯一索引的基本特性
-- 1. 唯一性:索引字段值必须唯一
-- 2. 可空性:允许NULL值(除非明确约束)
-- 3. 数量限制:可以有多个唯一索引
-- 4. 非聚集索引:创建非聚集索引

-- 创建带唯一索引的表
CREATE TABLE customers (
    id INT PRIMARY KEY AUTO_INCREMENT,
    customer_code VARCHAR(20) UNIQUE,
    email VARCHAR(100) UNIQUE,
    phone VARCHAR(20) UNIQUE,
    name VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 查看索引信息
SHOW INDEX FROM customers;

-- 另一种创建唯一索引的方式
CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    product_code VARCHAR(20),
    sku VARCHAR(30),
    name VARCHAR(100),
    
    UNIQUE KEY uk_product_code (product_code),
    UNIQUE KEY uk_sku (sku)
);
唯一索引约束
-- 唯一索引约束示例
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50),
    email VARCHAR(100),
    phone VARCHAR(20),
    
    -- 创建唯一索引
    UNIQUE KEY uk_username (username),
    UNIQUE KEY uk_email (email),
    UNIQUE KEY uk_phone (phone)
);

-- 测试唯一性约束
INSERT INTO users (username, email, phone) VALUES 
('john_doe', 'john@example.com', '1234567890');

-- 尝试插入重复值(会失败)
INSERT INTO users (username, email, phone) VALUES 
('john_doe', 'jane@example.com', '0987654321');
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

He1_Ma0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值