mysql(下)

1.数据约束

 1.1默认值

作用:当用户对使用默认值的字段不插入值的时候,就使用默认值。

注意:                        

                           1)对默认值字段插入null是可以的。

                           2)对默认值字段可以插入非null

CREATE TABLE student(

           id  INT,

           NAME  VARCHAR(20),

           address  VARCHAR(20) DEFAULT '广州天河'  --默认值

)


DROP TABLE student;

-- 当字段没有插入值的时候,mysql自动给该字段分配默认值

INSERT INTO student(id,NAME) VALUES(1,'张三');


-- 注意:默认值的字段允许为null

INSERT INTO student(id,NAME,address)

  VALUE(2,'李四',NULL);

INSERT INTO student(id,NAME,address)

  VALUE(3,'王五','广州番禺');

 1.2非空    

作用:限制字段必须赋值

 注意:

                   1)非空字符必须赋值

                    2)非空字符不能赋null

-- 需求: gender字段必须有值(不为null)

CREATE TABLE student(

           id  INT,

           NAME  VARCHAR(20),

           gender  VARCHAR(2) NOT NULL --非空

)


-- 非空字段必须赋值

INSERT INTO student(id,NAME) VALUES(1,'李四');

-- 非空字符不能插入null

INSERT INTO student(id,NAME,gender)

  VALUES(1,'李四',NULL);

     1.3  唯一

作用:对字段的值不能重复

                     注意:

                                          1)唯一字段可以插入null                                      

                                          2)唯一字段可以插入多个null

CREATE TABLE student(

           id  INT UNIQUE, --唯一

           NAME  VARCHAR(20)

)


INSERT INTO student(id,NAME)  VALUES(1,'zs');

INSERT INTO student(id,NAME)  VALUES(1,'lisi'); -- ERROR 1062 (23000): Duplicate entry '1' for key 'id'

INSERT INTO student(id,NAME)  VALUES(2,'lisi');

1.4  主键

          作用:非空+唯一

          注意:                          

        1)通常情况下,每张表都会设置一个主键字段。用于标记表中的每条记录的唯一性。

        2)建议不要选择表的包含业务含义的字段作为主键,建议给每张表独立设计一个非业务含义的id字段。

DROP TABLE student;

CREATE TABLE student(

           id  INT PRIMARY KEY, --主键

           NAME  VARCHAR(20)

)


INSERT INTO student(id,NAME) VALUES(1,'张三');

INSERT INTO student(id,NAME) VALUES(2,'张三');

-- INSERT INTO student(id,NAME)

  VALUES(1,'李四'); -- 违反唯一约束:Duplicate entry '1' for key  'PRIMARY'


-- insert into student(name) value('李四'); -- 违反非空约束:ERROR 1048 (23000): Column 'id' cannot be null


 1.5 自增长

作用:自动递增

CREATE TABLE student(

           id  INT(4) ZEROFILL PRIMARY KEY AUTO_INCREMENT, --自增长,从0开始  ZEROFILL零填充

           NAME  VARCHAR(20)

)


-- 自增长字段可以不赋值,自动递增

INSERT INTO student(NAME) VALUES('张三');

INSERT INTO student(NAME) VALUES('李四');

INSERT INTO student(NAME) VALUES('王五');


SELECT * FROM student;

-- 不能影响自增长约束

DELETE FROM student;

-- 可以影响自增长约束

TRUNCATE TABLE student;


1.6  外键

  作用:约束两种表的数据

         出现两种表的情况:

         解决数据冗余高问题:独立出一张表           

        例如:员工表  和  部门表            

         问题出现:在插入员工表数据的时候,员工表的部门ID字段可以随便插入!!!!! 


        使用外键约束:约束插入员工表的部门ID字段值

        解决办法:在员工表的部门ID字段添加一个外键约束


-- 部门表(主表)

CREATE TABLE dept(

           id INT PRIMARY KEY,

           deptName  VARCHAR(20)

)


-- 修改员工表(副表/从表)

CREATE TABLE employee(

           id  INT PRIMARY KEY,

           empName  VARCHAR(20),

           deptIdINT,--把部门名称改为部门ID

           --声明一个外键约束

           CONSTRAINT emlyee_dept_fk FOREIGN KEY(deptId) REFERENCES  dept(id)

           --           外键名称                  外键               参考表(参考字段)

)


    注意:

                                1)被约束的表称为副表,约束别人的表称为主表,外键设置在副表上的!!!

                                2)主表的参考字段通用为主键!

                                3)添加数据: 先添加主表,再添加副表

                                4)修改数据: 先修改副表,再修改主表

                                5)删除数据: 先删除副表,再删除主表

-- 员工表

CREATE TABLE employee(

           id  INT PRIMARY KEY,

           empName  VARCHAR(20),

           deptName  VARCHAR(20) --部门名称

)


INSERT INTO employee VALUES(1,'张三','软件开发部');

INSERT INTO employee VALUES(2,'李四','软件开发部');

INSERT INTO employee VALUES(3,'王五','应用维护部');


SELECT * FROM employee;


-- 添加员工,部门名称的数据冗余高

INSERT INTO employee VALUES(4,'陈六','软件开发部');


-- 解决数据冗余高的问题:给冗余的字段放到一张独立表中

-- 独立设计一张部门表

CREATE TABLE dept(

           id  INT PRIMARY KEY,

           deptName  VARCHAR(20)

)


DROP TABLE employee;


-- 修改员工表

CREATE TABLE employee(

           id  INT PRIMARY KEY,

           empName  VARCHAR(20),

           deptId  INT,--把部门名称改为部门ID

           --声明一个外键约束

           CONSTRAINT  emlyee_dept_fk FOREIGN KEY(deptId) REFERENCES dept(id) ON UPDATE CASCADE ON  DELETE CASCADE  -- ON CASCADE UPDATE:级联修改

           --           外键名称                  外键               参考表(参考字段)

)


INSERT INTO dept(id,deptName) VALUES(1,'软件开发部');

INSERT INTO dept(id,deptName) VALUES(2,'应用维护部');

INSERT INTO dept(id,deptName) VALUES(3,'秘书部');


INSERT INTO employee VALUES(1,'张三',1);

INSERT INTO employee VALUES(2,'李四',1);

INSERT INTO employee VALUES(3,'王五',2);

INSERT INTO employee VALUES(4,'陈六',3);


-- 问题: 该记录业务上不合法,员工插入了一个不存在的部门数据

INSERT INTO employee VALUES(5,'陈六',4); -- 违反外键约束:Cannot add or update a child row: a foreign key constraint fails  (`day16`.`employee`, CONSTRAINT `emlyee_dept_fk` FOREIGN KEY (`deptId`)  REFERENCES `dept` (`id`))


-- 1)当有了外键约束,添加数据的顺序:先添加主表,再添加副表数据

-- 2)当有了外键约束,修改数据的顺序:先修改副表,再修改主表数据

-- 3)当有了外键约束,删除数据的顺序:先删除副表,再删除主表数据

-- 修改部门(不能直接修改主表)

UPDATE dept SET id=4 WHERE id=3;

-- 先修改员工表

UPDATE employee SET deptId=2 WHERE id=4;


-- 删除部门

DELETE FROM dept WHERE id=2;


-- 先删除员工表

DELETE FROM employee WHERE deptId=2;


SELECT * FROM dept;

SELECT * FROM employee;

 

   1.7  级联操作

                     问题:当有了外键约束的时候,必须先修改或删除副表中的所有关联数据,才能修改或删除主表!但是,我们希望直接修改或删除主表数据,从而影响副表数据。可以使用级联操作实现!!!


                     级联修改:ON UPDATE CASCADE

                     级联删除:ON DELETE CASCADE


CREATE TABLE employee(

           id  INT PRIMARY KEY,

           empName  VARCHAR(20),

           deptId  INT,--把部门名称改为部门ID

           --声明一个外键约束

           CONSTRAINT  emlyee_dept_fk FOREIGN KEY(deptId) REFERENCES dept(id)ON UPDATE CASCADE ON DELETE CASCADE  -- ON CASCADE UPDATE:级联修改

           --           外键名称                  外键               参考表(参考字段)

)

注意: 级联操作必须在外键基础上使用


-- 级联修改(修改)

-- 直接修改部门

UPDATE dept SET id=5 WHERE id=4;


-- 级联删除

-- 直接删除部门

DELETE FROM dept WHERE id=1;




2. 数据库设计

        三大范式

设计原则:建议设计的表尽量遵守三大范式。

         第一范式:要求表的每个字段必须是不可分割的独立单元

         第二范式:在第一范式的基础上,要求每张表只表达一个意思。表的每个字段都和表的主键有依赖。

 employee(员工): 员工编号  员工姓名部门名称   订单名称  --违反第二范式

  员工表:员工编号  员工姓名部门名称  

 订单表: 订单编号  订单名称            --符合第二范式

        第三范式:在第二范式基础,要求每张表的主键之外的其他字段都只能和主键有直接决定依赖关系。

  员工表:员工编号(主键)员工姓名  部门编号 部门名 --符合第二范式,违反第三范式                                                                                                                                                                                  (数据冗余高)

 员工表:员工编号(主键)员工姓名  部门编号    --符合第三范式(降低数据冗余)

 部门表:部门编号  部门名




3. 关联查询(多表查询)

-- 需求:查询员工及其所在部门(显示员工姓名,部门名称)

-- 多表查询规则:1)确定查询哪些表   2)确定哪些哪些字段   3)表与表之间连接条件 (规律:连接条件数量是表数量-1)

-- 1. 内连接查询:只有满足条件的结果才会显示(使用最频繁)

SELECT empName,deptName       -- 2)确定哪些哪些字段

           FROM  employee,dept    -- 1)确定查询哪些表

           WHERE  employee.deptId=dept.id  -- 3)表与表之间连接条件

-- 内连接的另一种语法

SELECT empName,deptName

           FROM  employee

           INNER  JOIN dept

           ON  employee.deptId=dept.id;

-- 需求:查询每个部门的员工

-- 预期结果:

 --  软件开发部  张三

 --  软件开发部 李四

 --  应用维护部 王五

 --  秘书部     陈六

 --  总经办      null

-- 2. 左[外]连接查询:

使用左边表的数据去匹配右边表的数据,如果符合连接条件的结果则显示,如果不符合连接条件则显示null

 --(注意:左外连接:左表的数据一定会完成显示!)

SELECT d.deptName,e.empName

           FROM  dept d

           LEFT  OUTER JOIN employee e

           ON  d.id=e.deptId;

-- 3 .   右[外]连接查询:

 使用右边表的数据去匹配左边表的数据,如果符合连接条件的结果则显示,如果不符合连接条件则显示null

 --(注意:右外连接:右表的数据一定会完成显示!)

        SELECT d.deptName,e.empName

           FROM  employee e

           RIGHT  OUTER JOIN dept d

           ON  d.id=e.deptId;


-- 4. 自连接查询

-- 需求:查询员工及其上司

-- 预期结果:       

           --张三     null

           --李四    张三

           --王五    李四

           --陈六    王五

SELECT e.empName,b.empName

           FROM  employee e

           LEFT  OUTER JOIN employee b

           ON  e.bossId=b.id;




4. 存储过程

         1.什么是存储过程

        存储过程,带有逻辑的sql语句

          2.存储过程语法

-- 声明结束符

-- 创建存储过程

DELIMITER $

CREATE PROCEDURE pro_test()

BEGIN

           --可以写多个sql语句;

           SELECT  * FROM employee;

END $


-- 执行存储过程

CALL pro_test();


3.带有输入参数的存储过程

-- 需求:传入一个员工的id,查询员工信息

DELIMITER $

CREATE PROCEDURE pro_findById(IN eid  INT)  -- IN:输入参数

BEGIN

           SELECT  * FROM employee WHERE id=eid;

END $


-- 调用

CALL pro_findById(4);


4.带有输出参数的存储过程

DELIMITER $

CREATE PROCEDURE pro_testOut(OUT str  VARCHAR(20))  -- OUT:输出参数

BEGIN

  --给参数赋值

           SET  str='helljava';

END $


-- 删除存储过程

DROP PROCEDURE pro_testOut;

-- 调用

-- 如何接受返回参数的值??

-- ***mysql的变量******

-- 

  全局变量(内置变量):mysql数据库内置的变量(所有连接都起作用)

--查看所有全局变量:show  variables

--查看某个全局变量: select @@变量名

 --修改全局变量: set 变量名=新值


  -- character_set_client: mysql服务器的接收数据的编码


  -- character_set_results:mysql服务器输出数据的编码

 --  会话变量:只存在于当前客户端与数据库服务器端的一次连接当中。如果连接断开,那么会话变量全部丢失!

  --定义会话变量: set @变量=值

  --查看会话变量: select @变量

-- 局部变量:在存储过程中使用的变量就叫局部变量。只要存储过程执行完毕,局部变量就丢失!!


-- 1)定义一个会话变量name, 

    2)使用name会话变量接收存储过程的返回值

CALL pro_testOut(@NAME);

-- 查看变量值

SELECT @NAME;

-- 3.3 带有输入输出参数的存储过程

DELIMITER $

CREATE PROCEDURE pro_testInOut(INOUT n  INT)  -- INOUT:输入输出参数

BEGIN

  --查看变量

SELECT n;

 SET n =500;

END $


-- 调用

SET @n=10;


CALL pro_testInOut(@n);


SELECT @n;


-- 3.4 带有条件判断的存储过程

-- 需求:输入一个整数,如果1,则返回“星期一”,如果2,返回“星期二”,如果3,返回“星期三”。其他数字,返回“错误输入”;

DELIMITER $

CREATE PROCEDURE pro_testIf(IN num  INT,OUT str VARCHAR(20))

BEGIN

           IF  num=1 THEN

                     SET  str='星期一';

           ELSEIF  num=2 THEN

                     SET  str='星期二';

           ELSEIF  num=3 THEN

                     SET  str='星期三';

           ELSE

                     SET  str='输入错误';

           END  IF;

END $


CALL pro_testIf(4,@str);


SELECT @str;


-- 3.5 带有循环功能的存储过程

-- 需求:输入一个整数,求和。例如,输入100,统计1-100的和

DELIMITER $

CREATE PROCEDURE pro_testWhile(IN num  INT,OUT result INT)

BEGIN

           --定义一个局部变量

           DECLARE  i INT DEFAULT 1;

           DECLARE  vsum INT DEFAULT 0;

           WHILE  i<=num DO

                 SET vsum = vsum+i;

                 SET i=i+1;

           END  WHILE;

           SET  result=vsum;

END $


DROP PROCEDURE pro_testWhile;



CALL pro_testWhile(100,@result);


SELECT @result;


USE day16;


-- 3.6 使用查询的结果赋值给变量(INTO)

DELIMITER $

CREATE PROCEDURE pro_findById2(IN eid  INT,OUT vname VARCHAR(20) )

BEGIN

           SELECT  empName INTO vname FROM employee WHERE id=eid;

END $


CALL pro_findById2(1,@NAME);


SELECT @NAME;


6 触发器

              6.1触发器作用

                     当操作了某张表时,希望同时触发一些动作/行为,可以使用触发器完成!!

  例如:当向员工表插入一条记录时,希望同时往日志表插入数据

-- 需求:当向员工表插入一条记录时,希望mysql自动同时往日志表插入数据

-- 创建触发器(添加)

CREATE TRIGGER tri_empAdd AFTER INSERT ON  employee FOR EACH ROW    --当往员工表插入一条记录时

INSERT INTO test_log(content) VALUES('员工表插入了一条记录');

-- 插入数据

INSERT INTO employee(id,empName,deptId)

  VALUES(7,'扎古斯',1);

INSERT INTO employee(id,empName,deptId)

  VALUES(8,'扎古斯2',1);

-- 创建触发器(修改)

CREATE TRIGGER tri_empUpd AFTER UPDATE ON  employee FOR EACH ROW    --当往员工表修改一条记录时


  INSERT INTO test_log(content) VALUES('员工表修改了一条记录');

 --修改

 UPDATE employee SET empName='eric' WHERE  id=7;


-- 创建触发器(删除)

CREATE TRIGGER tri_empDel AFTER DELETE ON  employee FOR EACH ROW    --当往员工表删除一条记录时


  INSERT INTO test_log(content) VALUES('员工表删除了一条记录');


 --删除

 DELETE FROM employee WHERE id=7;


7  mysql权限问题

 --  mysql数据库权限问题:root :拥有所有权限(可以干任何事情)

 --权限账户,只拥有部分权限(CURD) 例如,只能操作某个数据库的某张表

 --如何修改mysql的用户密码?

 --  password: md5加密函数(单向加密)

 SELECT PASSWORD('root'); --  *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B

--  mysql数据库,用户配置 : user表

USE mysql;


SELECT * FROM USER;


-- 修改密码

UPDATE USER SET  PASSWORD=PASSWORD('123456') WHERE USER='root';


-- 分配权限账户

GRANT SELECT ON day16.employee TO  'eric'@'localhost' IDENTIFIED BY '123456';

GRANT DELETE ON day16.employee TO  'eric'@'localhost' IDENTIFIED BY '123456';

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,671评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,442评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,524评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,623评论 1 275
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,642评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,584评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,953评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,621评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,865评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,608评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,698评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,378评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,958评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,940评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,173评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,419评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,425评论 2 342

推荐阅读更多精彩内容