当前位置: 首页 > wzjs >正文

深圳网站制作的公司怎么样今日头条新闻在线看

深圳网站制作的公司怎么样,今日头条新闻在线看,茶文化网站开发论文,wordpress图片自动添加altMySQL表的约束 MySQL表的约束 1. 空属性 2. 默认值 3. 列描述 4. zerofill 5. 主键 6. 自增长 7. 唯一键 8. 外键 9. 综合案例 MySQL表的约束 说到 MySQL 表的约束,这绝对是数据库设计里绕不开的一个话题。很多人一提“约束”,第一反应可能是字段的数据…

MySQL表的约束

MySQL表的约束
1. 空属性
2. 默认值
3. 列描述
4. zerofill
5. 主键
6. 自增长
7. 唯一键
8. 外键
9. 综合案例


MySQL表的约束

说到 MySQL 表的约束,这绝对是数据库设计里绕不开的一个话题。很多人一提“约束”,第一反应可能是字段的数据类型,比如 INT 不能存字符串,VARCHAR 有长度限制。这当然是最基本的一层限制,但光靠这些,远远不够。就像你家门口装了密码锁,结果厨房窗户忘关了——防得了一部分,还是会漏。

这时候就得靠表级的各种约束来兜底,从业务逻辑的角度出发,帮你把不合理的数据挡在门外。

举个栗子🌰:假设你建了一个用户表,里面有个“年龄”字段,类型是 INT。这时候要是有人输入个 -100 或者 999999999 岁,数据库是能存下没错,但你一看就知道这不靠谱。这种数值范围的控制,其实属于“检查约束(CHECK)”。不过早期的 MySQL 并不支持这玩意儿(8.0 开始才支持),所以我们今天先不展开这个,重点聊聊其他你在开发里经常用到的约束类型。

这篇文章我们就来盘讲讲这些实用技能:空属性、默认值、列描述、zerofill、主键、自增长、唯一键、外键。最后还会用一个综合案例,把这些知识点串起来,帮你真正掌握这些“看起来简单但常常出问题”的细节。

1. 空属性

1.1 NULL和NOT NULL的相爱相杀

数据库里默认所有字段都是允许为空的(NULL),就像你家的冰箱——什么都能塞进去。但实际开发中,咱们得学会"断舍离",把不该空的字段锁死。为啥?因为空值是个麻烦精!它参与运算时会直接让结果变NULL,就像往火锅里倒可乐——全毁了。

举个例子🌰:假设你统计销售额,某个订单金额是NULL,那么SELECT SUM(price)的结果也会是NULL。这时候老板要是问"今天赚了多少",你只能尴尬地回一句:“不知道啊,有笔订单金额没填…”

所以遇到必填项,一定要用NOT NULL。比如班级表的教室字段:

CREATE TABLE class(class_name VARCHAR(20) NOT NULL,classroom VARCHAR(20) NOT NULL
);

这时候插入数据时,这两个字段就必须填,否则MySQL会直接报错:

INSERT INTO class(class_name) VALUES('三年二班');
-- 报错:Field 'classroom' doesn't have a default value

1.2 NULL的隐藏陷阱

很多人以为NULL就是"没有值",其实它更像"未知值"。比如两个NULL比较时,既不等于也不等于不,永远返回UNKNOWN。这会导致查询时出现意想不到的结果:

SELECT * FROM users WHERE email = NULL; -- 查不到任何数据
SELECT * FROM users WHERE email IS NULL; -- 才能查到空邮箱用户

1.3 NOT NULL的进阶玩法

有时候我们会给字段设置默认值,这时候再加NOT NULL就显得多余了。比如:

CREATE TABLE user(id INT PRIMARY KEY AUTO_INCREMENT,gender ENUM('男','女') DEFAULT '男' NOT NULL
);

这里的NOT NULL其实可以省略,因为默认值已经保证了字段不为空。但要注意默认值的类型匹配,比如用字符串’0’当默认值,字段类型却是INT的话,可能会触发隐式转换。


2. 默认值

2.1 DEFAULT的魔法时刻

默认值就像自动售货机——当你不投币时,它自己吐出预设的商品。比如用户表的性别字段:

CREATE TABLE user(id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(20),gender ENUM('男','女') DEFAULT '男'
);

这时候插入数据时,如果不指定gender字段,就会自动填充"男":

INSERT INTO user(name) VALUES('张三');
-- 实际插入的是('张三', '男')

2.2 默认值的进阶套路

默认值不仅能用常量,还能用表达式(MySQL 8.0+支持):

CREATE TABLE orders(order_id INT PRIMARY KEY AUTO_INCREMENT,create_time DATETIME DEFAULT NOW(),expire_time DATETIME DEFAULT (NOW() + INTERVAL 7 DAY)
);

不过要注意,同一个字段不能同时有默认值和NOT NULL约束(除非默认值明确指定),否则会触发冲突。

2.3 默认值的隐藏彩蛋

对于日期时间类型字段,默认值有特殊规则:

  • DATETIME默认值只能是常量,不能用函数
  • TIMESTAMP会自动设置当前时间作为默认值(如果未显式指定)

比如:

CREATE TABLE test(id INT PRIMARY KEY AUTO_INCREMENT,dt DATETIME,           -- 默认值为NULLts TIMESTAMP           -- 默认值自动变为CURRENT_TIMESTAMP
);

3. 列描述

3.1 COMMENT的文艺复兴

列描述就像给数据库字段写小纸条,方便后来人看懂你的设计思路。比如用户表:

CREATE TABLE user(id INT PRIMARY KEY COMMENT '用户ID',name VARCHAR(20) COMMENT '用户真实姓名',nickname VARCHAR(20) COMMENT '用户昵称(可为空)'
);

通过SHOW CREATE TABLE user;就能看到这些注释:

CREATE TABLE `user` (`id` int(11) NOT NULL COMMENT '用户ID',`name` varchar(20) NOT NULL COMMENT '用户真实姓名',`nickname` varchar(20) DEFAULT NULL COMMENT '用户昵称(可为空)'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

3.2 描述的最佳实践

  1. 业务含义:说明字段的业务逻辑,比如status TINYINT COMMENT '状态:1-待支付 2-已支付 3-已发货'
  2. 数据来源:标明数据是怎么来的,比如score DECIMAL(5,2) COMMENT '根据考试成绩自动同步'
  3. 变更记录:重要字段的变更历史,比如address VARCHAR(255) COMMENT '2022.3新增,原地址字段已废弃'

3.3 描述的隐藏功能

结合INFORMATION_SCHEMA.COLUMNS表,可以实现自动化文档生成:

SELECT COLUMN_NAME, COLUMN_COMMENT 
FROM information_schema.columns
WHERE TABLE_SCHEMA='your_db' AND TABLE_NAME='user';

4. zerofill

4.1 数字显示的艺术

zerofill就像给数字穿上西装打上领带——让它看起来更正式。比如订单编号:

CREATE TABLE orders(order_id INT(6) ZEROFILL PRIMARY KEY AUTO_INCREMENT
);

插入数据时:

INSERT INTO orders() VALUES();
-- 实际显示order_id为000001

注意这里的INT(6)不是指6位数字,而是显示宽度。底层存储还是标准的INT类型(4字节)。

4.2 zerofill的连带效应

使用zerofill会自动触发UNSIGNED属性:

CREATE TABLE test(a INT(5) ZEROFILL);
-- 实际相当于 INT(5) UNSIGNED ZEROFILL

所以字段只能存储正数,负数插入会变成0。

4.3 使用场景分析

适合需要固定显示位数的业务场景:

  • 学号:202301010001(年份+学院代码+序号)
  • 发票号码:0000123456
  • 产品编号:P000001

但要注意,这种格式化更适合前端处理,数据库层面保持纯粹数字更利于计算。


5. 主键

5.1 数据的身份证

主键就像每个人的身份证号码——必须唯一且不能为空。创建学生表:

CREATE TABLE student(stu_id CHAR(10) PRIMARY KEY COMMENT '学号(唯一标识)',name VARCHAR(20)
);

这时候插入重复学号会直接报错:

INSERT INTO student VALUES('2023010101','张三');
INSERT INTO student VALUES('2023010101','李四');
-- 报错:Duplicate entry '2023010101' for key 'PRIMARY'

5.2 主键的进阶操作

  1. 删除主键

    ALTER TABLE student DROP PRIMARY KEY;
    

    注意:如果该列有自增属性,需要先删除自增

  2. 修改主键

    ALTER TABLE student MODIFY stu_id CHAR(12);
    -- 修改字段类型不影响主键约束
    
  3. 复合主键

    CREATE TABLE cart(user_id INT,product_id INT,quantity INT,PRIMARY KEY(user_id, product_id)
    );
    

    这时候单个字段可以重复,但组合必须唯一

5.3 主键选择的玄学

  1. 自增主键 vs 业务主键
    自增主键(如AUTO_INCREMENT)更利于索引性能,业务主键(如身份证号)更直观,需要根据场景权衡

  2. UUID的另类玩法

    CREATE TABLE orders(order_id CHAR(36) PRIMARY KEY DEFAULT UUID(),...
    );
    

    适合分布式系统,但会占用更多存储空间


6. 自增长

6.1 AUTO_INCREMENT的魔法

自增字段就像自动步枪——每次扣动扳机都会自动装弹。创建文章表:

CREATE TABLE articles(article_id INT AUTO_INCREMENT PRIMARY KEY,title VARCHAR(100)
);

插入数据时:

INSERT INTO articles(title) VALUES('MySQL约束详解');
-- article_id自动分配为1
INSERT INTO articles(title) VALUES('性能优化技巧');
-- article_id自动分配为2

6.2 自增的隐藏技巧

  1. 指定初始值

    CREATE TABLE users(id INT AUTO_INCREMENT PRIMARY KEY
    ) AUTO_INCREMENT = 1000;
    
  2. 跳增现象
    如果插入失败或事务回滚,自增值不会回退。比如插入100后失败,下一个值会是101而不是100

  3. 手动赋值

    INSERT INTO articles(article_id, title) VALUES(10000, '特别推荐');
    -- 下次自增值从10001开始
    

6.3 自增的性能考量

  1. 并发问题
    InnoDB引擎使用互斥锁来确保自增的连续性,在高并发场景可能成为瓶颈

  2. 缓存配置
    innodb_autoinc_lock_mode参数影响自增行为,需要根据业务调整

  3. 迁移风险
    导出导入数据时,记得检查自增字段的当前值:

    SHOW TABLE STATUS LIKE 'articles';
    -- 查看Auto_increment列
    

7. 唯一键

7.1 除主键外的唯一保障

唯一键就像班级里的学号和电话号码——都可以唯一标识学生,但只能选一个当主键。创建用户表:

CREATE TABLE user(id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(20) UNIQUE,email VARCHAR(50) UNIQUE
);

这时候用户名和邮箱都必须唯一:

INSERT INTO user(username, email) 
VALUES('zhangsan', 'zhangsan@example.com');-- 插入相同用户名会失败
INSERT INTO user(username, email) 
VALUES('zhangsan', 'zs@example.com');
-- 报错:Duplicate entry 'zhangsan' for key 'username'

7.2 唯一键的骚操作

  1. 复合唯一键

    CREATE TABLE exam(student_id INT,subject VARCHAR(20),score INT,UNIQUE(student_id, subject)
    );
    

    保证同一个学生同一科目只有一条记录

  2. 空值处理
    唯一键允许有多个NULL值(这与主键不同):

    INSERT INTO user(username) VALUES(NULL);
    INSERT INTO user(username) VALUES(NULL);
    -- 两条记录都能成功插入
    
  3. 延迟约束
    在事务中,唯一约束检查可以延迟到提交时:

    SET CONSTRAINTS ALL DEFERRED;
    -- 需要配合支持的存储引擎
    

7.3 唯一键的优化技巧

  1. 前缀索引
    对长字符串字段,可以只索引前缀:

    CREATE TABLE products(id INT PRIMARY KEY,product_code VARCHAR(100) UNIQUE
    );
    -- 改为
    CREATE UNIQUE INDEX idx_code ON products(product_code(20));
    
  2. 合并索引
    如果某个查询经常同时用到username和email,可以创建联合唯一索引:

    CREATE UNIQUE INDEX idx_user_email ON user(username, email);
    

8. 外键

8.1 表之间的羁绊

外键就像亲子关系——孩子必须知道自己爹是谁。创建订单表:

CREATE TABLE orders(order_id INT PRIMARY KEY AUTO_INCREMENT,user_id INT,FOREIGN KEY(user_id) REFERENCES users(id)
);

这时候插入订单时:

-- 假设users表中没有id=100的用户
INSERT INTO orders(user_id) VALUES(100);
-- 报错:Cannot add or update a child row

8.2 外键的连环反应

  1. 级联更新
    当父表主键变更时,子表自动更新:

    CREATE TABLE orders(order_id INT PRIMARY KEY AUTO_INCREMENT,user_id INT,FOREIGN KEY(user_id) REFERENCES users(id) ON UPDATE CASCADE
    );
    
  2. 级联删除
    删除父表记录时,自动删除子表关联数据:

    FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
    
  3. 置空操作
    删除父表记录时,将子表外键字段设为NULL:

    FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE SET NULL
    -- 注意:字段必须允许NULL
    

8.3 外键的性能博弈

  1. 锁机制
    修改父表主键时,会锁定子表相关记录,可能引发死锁

  2. 批量导入
    导入大量数据时,建议先关闭外键检查:

    SET FOREIGN_KEY_CHECKS=0;
    -- 执行导入操作
    SET FOREIGN_KEY_CHECKS=1;
    
  3. 索引优化
    外键字段必须有索引,否则会影响性能:

    CREATE INDEX idx_user ON orders(user_id);
    -- 如果创建外键时未自动创建
    

9. 综合案例

9.1 商城系统的数据设计

让我们来设计一个简单的电商系统,包含三个核心表:

9.1.1 商品表(goods)
CREATE TABLE goods(goods_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '商品ID',goods_name VARCHAR(100) NOT NULL COMMENT '商品名称',unitprice DECIMAL(10,2) NOT NULL COMMENT '单价',category VARCHAR(50) COMMENT '分类',provider VARCHAR(100) COMMENT '供应商',stock INT DEFAULT 0 COMMENT '库存',INDEX idx_category(category)
) ENGINE=InnoDB;
9.1.2 客户表(customer)
CREATE TABLE customer(customer_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '客户ID',name VARCHAR(20) NOT NULL COMMENT '姓名',address VARCHAR(200) COMMENT '住址',email VARCHAR(50) UNIQUE COMMENT '邮箱',sex ENUM('男','女') COMMENT '性别',card_id CHAR(18) UNIQUE COMMENT '身份证',reg_time DATETIME DEFAULT NOW() COMMENT '注册时间'
) ENGINE=InnoDB;
9.1.3 购买表(purchase)
CREATE TABLE purchase(order_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '订单号',customer_id INT NOT NULL COMMENT '客户ID',goods_id INT NOT NULL COMMENT '商品ID',nums INT NOT NULL DEFAULT 1 COMMENT '购买数量',order_time DATETIME DEFAULT NOW(),FOREIGN KEY(customer_id) REFERENCES customer(customer_id),FOREIGN KEY(goods_id) REFERENCES goods(goods_id),INDEX idx_time(order_time)
) ENGINE=InnoDB;

9.2 设计亮点解析

  1. 约束组合拳

    • 客户姓名NOT NULL保证必填
    • 邮箱和身份证UNIQUE防止重复
    • 性别用ENUM限制取值范围
    • 购买数量DEFAULT 1避免零值
  2. 性能优化

    • 商品分类添加索引
    • 订单时间建立索引方便按时间查询
  3. 数据完整性

    • 外键约束确保订单中的客户和商品真实存在
    • 级联操作可自行添加(根据业务需求)

9.3 扩展思考

  1. 库存扣减
    在购买表插入记录时,需要更新商品表库存。可以通过触发器实现:

    DELIMITER //
    CREATE TRIGGER after_purchase_insert 
    AFTER INSERT ON purchase
    FOR EACH ROW
    BEGINUPDATE goods SET stock = stock - NEW.nums WHERE goods_id = NEW.goods_id;
    END//
    DELIMITER ;
    
  2. 订单状态
    可以添加status字段表示订单状态(待支付、已发货等),配合外键关联状态字典表

  3. 分区策略
    对于大规模数据,可以按订单时间做分区:

    CREATE TABLE purchase(...) 
    PARTITION BY RANGE (YEAR(order_time)) (PARTITION p2022 VALUES LESS THAN (2023),PARTITION p2023 VALUES LESS THAN (2024)
    );
    
http://www.dtcms.com/wzjs/393097.html

相关文章:

  • 电子商务网站建设课程设计思路黄冈地区免费网站推广平台
  • 泰安企业建站公司平台蔡甸seo排名公司
  • 网站和网页的概念百度自动搜索关键词软件
  • 汕头市澄海建设局门户网站网络整合营销公司
  • 公司做网站有什么好处直通车关键词优化
  • wordpress多站点用户互通百度人工客服电话怎么转人工
  • 北京 网站建设济南seo小黑seo
  • 最新网站源码网站域名注册查询
  • 怎样建设一个网站教学谷歌搜索引擎363入口
  • 手机端开发网站模板下载优化大师下载安装
  • 网站设计总结与心得体会武汉seo公司排名
  • 成都电子商务平台网站制作报价2022搜索引擎
  • 做网站 做手机app要学什么软件吸引人的微信软文
  • 洛阳航迪科技网站建设公司怎么样解封后中国死了多少人
  • 自己做短视频网站推广网站平台
  • 做poster的网站b2b外贸接单平台
  • 樱花草视频在线观看高清免费观看seo就业哪家好
  • 住小帮装修效果图佛山seo教程
  • 建设网站门户网站子域名查询
  • 无锡做公司网站竞价托管就选微竞价
  • 网站建设与运营的课程标准天琥设计培训学校官网
  • 多语言外贸网站制作蚁坊软件舆情监测系统
  • 在哪里建立个人网站广州最新发布最新
  • ppt做仿网站点击效果电脑优化大师有用吗
  • 漳州网站优化南宁百度seo
  • 哪一些网站可以开户做百度广告网站推广苏州
  • 网站备案下来以后怎么做网页seo独立站优化
  • 管庄地区网站建设嵌入式培训
  • 哪公司建设网站网络优化公司有哪些
  • 宿州网站建设贰聚思诚信seo优化方案策划书