MySQL 支持多种数据类型,选择合适的类型对性能和存储空间都很重要。这里先做个概览,后续章节会进行详细讲解。下面将根据不同的类型对类型进行分类整理:
用来存储数字,如整数、浮点数等的数据类型,如下表:
| 类型 | 存储空间 | 有符号范围 | 无符号范围 |
| TINYINT | 1字节 | -128 ~ 127 | 0 ~ 255 |
| SMALLINT | 2字节 | -32768 ~ 32767 | 0 ~ 65535 |
| MEDIUMINT | 3字节 | -8388608 ~ 8388607 | 0 ~ 16777215 |
| INT/INTEGER | 4字节 | -21亿 ~ 21亿 | 0 ~ 43亿 |
| BIGINT | 8字节 | 极大范围 | 极大范围 |
| FLOAT | 4字节 | 单精度浮点数 | - |
| DOUBLE | 8字节 | 双精度浮点数 | - |
| DECIMAL | 变长 | 定点数,精度准确 | - |
用来存储字符串的类型,如存储字符、存储长文本等等,如下表:
| 类型 | 最大长度 | 特点 |
| CHAR(n) | 255字符 | 定长,不够补空格,查询快 |
| VARCHAR(n) | 65535字节 | 变长,节省空间,查询稍慢 |
| TINYTEXT | 255字节 | 小文本 |
| TEXT | 65535字节 | 普通文本 |
| MEDIUMTEXT | 16MB | 中等文本 |
| LONGTEXT | 4GB | 大文本 |
| BLOB | 65535字节 | 二进制数据 |
用来存储日期和时间的类型,如下表:
| 类型 | 格式 | 范围 | 特性 |
| DATE | YYYY-MM-DD | 1000-01-01 ~ 9999-12-31 | 日期 |
| TIME | HH:MM:SS | -838:59:59 ~ 838:59:59 | 时间 |
| DATETIME | YYYY-MM-DD HH:MM:SS | 1000-01-01 ~ 9999-12-31 | 日期时间 |
| TIMESTAMP | YYYY-MM-DD HH:MM:SS | 1970-01-01 ~ 2038-01-19 | 带时区,自动更新 |
| YEAR | YYYY | 1901 ~ 2155 | 年份 |
除了上面常见的三大类型外,还支持其他一些数据类型:
ENUM:枚举类型,只能从预定义值中选择
SET:集合类型,可以选择多个预定义值
JSON:MySQL 5.7.8+ 支持的JSON数据类型
BOOLEAN:MySQL中的布尔类型实际是 TINYINT(1) 的别名
为了更好地理解数据类型,我们来创建一个简化版的电商数据库,包含用户、商品、订单等表。例如:
(1)创建数据库
mysql> CREATE DATABASE IF NOT EXISTS ecommerce
-> CHARACTER SET utf8mb4
-> COLLATE utf8mb4_unicode_ci;
Query OK, 1 row affected (0.00 sec)(2)切换到 ecommerce 数据库
mysql> USE ecommerce;
Database changed(3)创建用户表
mysql> CREATE TABLE users (
-> user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户ID',
-> username VARCHAR(50) NOT NULL COMMENT '用户名',
-> password_hash VARCHAR(255) NOT NULL COMMENT '密码哈希',
-> email VARCHAR(100) NOT NULL COMMENT '邮箱',
-> phone VARCHAR(20) COMMENT '手机号',
-> real_name VARCHAR(50) COMMENT '真实姓名',
-> gender TINYINT(1) DEFAULT 0 COMMENT '性别:0保密,1男,2女',
-> birthday DATE COMMENT '生日',
-> status TINYINT(1) DEFAULT 1 COMMENT '状态:1正常,0禁用',
-> created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间',
-> updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-> UNIQUE KEY uk_username (username),
-> UNIQUE KEY uk_email (email)
-> ) ENGINE=InnoDB COMMENT='用户表';
Query OK, 0 rows affected, 2 warnings (0.01 sec)(4)创建商品分类表
mysql> CREATE TABLE categories (
-> category_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '分类ID',
-> parent_id INT DEFAULT 0 COMMENT '父分类ID,0为顶级分类',
-> category_name VARCHAR(100) NOT NULL COMMENT '分类名称',
-> sort_order INT DEFAULT 0 COMMENT '排序序号',
-> is_show TINYINT(1) DEFAULT 1 COMMENT '是否显示',
-> created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-> INDEX idx_parent (parent_id)
-> ) ENGINE=InnoDB COMMENT='商品分类表';
Query OK, 0 rows affected, 1 warning (0.01 sec)(5)创建商品表
mysql> CREATE TABLE products (
-> product_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '商品ID',
-> product_code VARCHAR(50) NOT NULL COMMENT '商品编码',
-> product_name VARCHAR(200) NOT NULL COMMENT '商品名称',
-> category_id INT NOT NULL COMMENT '分类ID',
-> price DECIMAL(10, 2) NOT NULL COMMENT '售价',
-> market_price DECIMAL(10, 2) COMMENT '市场价',
-> cost_price DECIMAL(10, 2) COMMENT '成本价',
-> stock INT DEFAULT 0 COMMENT '库存',
-> unit VARCHAR(20) COMMENT '单位',
-> main_image VARCHAR(500) COMMENT '主图URL',
-> description TEXT COMMENT '商品描述',
-> detail LONGTEXT COMMENT '商品详情(HTML)',
-> is_on_sale TINYINT(1) DEFAULT 1 COMMENT '是否上架',
-> is_hot TINYINT(1) DEFAULT 0 COMMENT '是否热销',
-> is_new TINYINT(1) DEFAULT 0 COMMENT '是否新品',
-> created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-> updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-> UNIQUE KEY uk_code (product_code),
-> INDEX idx_category (category_id),
-> INDEX idx_price (price),
-> INDEX idx_status (is_on_sale)
-> ) ENGINE=InnoDB COMMENT='商品表';
Query OK, 0 rows affected, 3 warnings (0.01 sec)(6)创建订单表
mysql> CREATE TABLE orders (
-> order_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '订单ID',
-> order_no VARCHAR(32) NOT NULL COMMENT '订单编号',
-> user_id INT NOT NULL COMMENT '用户ID',
-> total_amount DECIMAL(12, 2) NOT NULL COMMENT '订单总金额',
-> discount_amount DECIMAL(12, 2) DEFAULT 0 COMMENT '优惠金额',
-> freight_amount DECIMAL(10, 2) DEFAULT 0 COMMENT '运费',
-> pay_amount DECIMAL(12, 2) NOT NULL COMMENT '应付金额',
-> status TINYINT(1) DEFAULT 0 COMMENT '订单状态:0待付款,1待发货,2待收货,3已完成,4已取消',
-> pay_time TIMESTAMP NULL COMMENT '支付时间',
-> ship_time TIMESTAMP NULL COMMENT '发货时间',
-> receive_time TIMESTAMP NULL COMMENT '收货时间',
-> created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-> updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-> UNIQUE KEY uk_order_no (order_no),
-> INDEX idx_user (user_id),
-> INDEX idx_status (status),
-> INDEX idx_created (created_at)
-> ) ENGINE=InnoDB COMMENT='订单表';
Query OK, 0 rows affected, 1 warning (0.01 sec)(7)创建订单商品明细表
mysql> CREATE TABLE order_items (
-> item_id INT AUTO_INCREMENT PRIMARY KEY,
-> order_id INT NOT NULL COMMENT '订单ID',
-> product_id INT NOT NULL COMMENT '商品ID',
-> product_name VARCHAR(200) NOT NULL COMMENT '商品名称(快照)',
-> product_image VARCHAR(500) COMMENT '商品图片(快照)',
-> price DECIMAL(10, 2) NOT NULL COMMENT '成交单价',
-> quantity INT NOT NULL COMMENT '数量',
-> subtotal DECIMAL(12, 2) NOT NULL COMMENT '小计金额',
-> INDEX idx_order (order_id)
-> ) ENGINE=InnoDB COMMENT='订单商品明细表';
Query OK, 0 rows affected (0.01 sec)上述这个数据库的设计遵循了一些基本原则:
命名规范:表名使用复数形式,字段名使用蛇形命名法
主键设计:统一使用自增ID作为主键,业务相关的唯一性约束用唯一索引实现
注释完善:每个字段和表都添加了中文注释
冗余设计:订单表中存储了商品名称和图片的快照,防止商品修改后订单历史数据丢失
索引优化:在常用的查询条件字段上创建了索引
更多知识请阅读后续章节……谢谢!!!