• mysql基础操作(三):数据约束


    首先创建一个数据库

    create database homework default character set utf8;
    use homework;

    1.1 默认值约束(default)

    -- 数据约束问题
    create table test(
    	name varchar(20),
    	gender varchar(2)
    );
    insert into test(name) values('张三');
    select * from test;
    drop table test;
    

    -- 需求:当不插入gender的时候,分配一个'男'的默认值
    create table test(
    	name varchar(20),
    	gender varchar(2) default '男'
    );
    



    1.2非空约束

    create table test(
    	name varchar(20),
    	gender varchar(2)
    );
    -- 需求:name字段一定要有值(不能不插入数据,不能是null)
    -- 这是给name添加非空约束
    create table test(
    	name varchar(20) not null,
    	gender varchar(2)
    );



    1.3唯一约束(unique)

    -- 需求:id的值不能出现出现重复值
    create table test(
    	id int unique,
    	name varchar(20)
    );
    -- 唯一约束可以插入多个null;
    -- 唯一约束可以为null;null并非一个数据,唯一约束不能约束null




    1.4主键约束(primary key 唯一+非空)

    -- 注意:
    -- 1)通常情况下,我们会给每张表都会设置一个主键字段
    --    用来标记记录的唯一性。
    -- 2)不建议把业务含义的字段设置为主键,因为随着业务的变化,
    -- 	  业务可能会出现重复。
    -- 3)建议给每张表添加一个独立的id字段,
    --    把这个id字段设置成主键,用来作为记录的唯一性。
    drop table test;
    
    
    create table test(
    	id int primary key,
    	name varchar(20)
    );





    1.5自增长约束:初始值为0,每 次递增1

    -- 需求:id的值不需要我们开发者管理,交给数据库维护,
    -- 这时给id添加自增长约束。
    
    
    create table test(
    	id int primary key auto_increment,
    	name varchar(20)
    );
    




    1.6外键约束(foreign key)

    -- 外键作用:约束两张表的数据
    -- 问题:约束哪种情况下的两张表呢?
    
    
    -- 员工表
    create table employee(
    	id int primary key auto_increment,
    	name varchar(20),
    	deptName varchar(20)  -- 部门名称
    );
    
    insert into employee(name, deptName)values('张三', '软件开发部'),
    	('李四', '软件维护部'),
    	('王五', '软件开发部'),
    	('李四', '软件维护部'),
    	('王五', '软件开发部');
    -- 问题:每次插入员工数据时,部门数据都会出现重复(冗余)
    -- 如果数据出现了冗余,那么会浪费数据库的存储空间的。
    -- 如何解决部门名称数据冗余的问题?
    -- 这时候就可以设置一张独立的部门表,把部门名称放到部门表中。

    使用主键唯一:

    drop table employee;
    -- 员工表                   解决冗余问题
    create table employee(
    	id int primary key auto_increment,
    	name varchar(20),
    	deptId int
    );
    -- 部门表
    create table dept(
    	id int primary key auto_increment,
    	deptName varchar(20)
    );
    insert into dept(name) values('软件开发部'), ('软件维护部');
    insert into employee(name, deptId) values('陈六', 1), 
    	('王五', 2); 


    外键约束

    -- 问题:在插入员工表的部门id的时候,插入了不存在的部门id
    -- 如何防止这种不合法的数据插入?  
    -- 添加外键约束(foreign key)
    -- 需求:deptId字段值来自于dept表的id字段的值,
    -- 这时就可以给deptId添加一个外键约束的值。
    drop table employee;
    -- 员工表(副表:被别人约束的表。外键设置在副表)            
    create table employee(
    	id int primary key auto_increment,
    	name varchar(20),
    	deptId int, 
     -- constraint 约束;强制;限制
    	constraint employee_dept_fk foreign key(deptId) references dept(id)
    --  定义一个名字  外键的名称               外键字段   参考     部门表的id
    );
    -- 部门表(主表:约束别人的表)
    create table dept(
    	id int primary key auto_increment,
    	deptName varchar(20)
    );
    insert into dept(name) values('软件开发部'), ('软件维护部');
    insert into employee(name, deptId) values('陈六', 1), 
    	('王五', 2); 
    

    外键约束在什么情况下会起作用?

    -- 这里设置的主表为部门表,主表只有两个部门:对应id为1 和 2
    -- 插入数据:当往副表插入了主表不存在的数据(超过范围)的时候,外键起作用  
    insert into employee(name, deptId)values('王五',3);
    -- 修改数据:当往副表修改了主表不存在的数据(超过范围)的时候,外键起作用
    update employee set deptId=3 where id=2;
    -- 删除数据:当删除主表中被副表引用的数据的时候,外键起作用
    delete from dept where id=1;

    -- 当有了外键之后,应该如何管理数据呢?
    -- 插入数据:先插入主表的数据,再插入副表的数据
    -- 修改数据:先修改主表数据,再修改副表数据
    -- 删除数据:先删除副表数据,再删除主表数据
    
    -- 删除了外键表中的数据,删除了没有外键表中的数据;在重新向没有外键的表中插入数据时出错
    -- 删除所有重建才行?考虑是主键的原因
    
    -- 目前的的解决方法只有一种:先将外键设置为0,待删除之后,再把外键设置为1
    
    -- SET foreign_key_checks=0;   
    -- SET foreign_key_checks=1;

    mysql中的update补充:

    -- mysql的update语句只支持更新前多少行,不支持从某行到另一行,比如 
    UPDATE tb_name SET column_name='test' ORDER BY id ASC LIMIT 30; 
    -- 更新前30行的某个字段内容,没什么问题。
    
    UPDATE tb_name SET column_name='test' ORDER BY id ASC LIMIT 20,10; 
    -- 更新从20行到30行的某个字段的内容,这样会报错。
    
    -- 解决办法就是采用子查询的方式 
    UPDATE tb_name SET column_name='test' WHERE id in (SELECT id FROM (SELECT * FROM tb_name ORDER BY id ASC LIMIT 20,10) AS tt); 
    -- 这样就能实现更新表中根据id升序排序的第20条到第30条数据的某个字段的内容


    字段类型补充:

    -- char(20) vs varchar(20)
    -- char(20):固定长度的字符串。不管实际存储的数据的大小,一定占用20个字符空间。
    -- varchar(20):可变长度的字符串。占用的空间大小就是实际存储的数据大小。


    int vs  int(4):

    -- int:默认最多11位,长度可根据实际存储的数值的长度
    -- int(4):固定的数值长度

    浮点数和定点数:

    c1 FLOAT(10,2),
    c2 DECIMAL(10,2)

    零填充:

    create table test(
    	id1 int,
    	id2 int(4) zerofill  -- zerofill:零填充
    )
    insert into test values(1, 1);
    select * from test;
    -- 显示的结果是:
    -- id1    id2
    -- 1      0001

    date vs datetime vs timestamp:

    -- date:日期     即使你输入的数据是 日期+时间 也只会记录日期
    -- datetime:日期+时间 
    -- timestamp:时间戳   不用输入数据,系统会自动记录当前的时间
    -- 每次插入或者更新的时候,系统都会更新时间。
    
    create table test_date(
    		date1 date,
    		date2 datetime,
    		date3 timestamp
    )
    insert into test_date(date1, date2)values('2015-06-17', '2015-06-17 17:35:45');
    select * from student;
    






    字段类型补充:
  • 相关阅读:
    59. Spiral Matrix II
    58. Length of Last Word
    57. Insert Interval
    56. Merge Intervals
    55. Jump Game
    54. Spiral Matrix
    53. Maximum Subarray
    52. N-Queens II
    51. N-Queens
    java封装学习
  • 原文地址:https://www.cnblogs.com/mzywucai/p/11053499.html
Copyright © 2020-2023  润新知