时间:2021-07-01 10:21:17 帮助过:20人阅读
注:外键约束只有在数据库引擎为InnoDB时有效!!!
2.2修改数据库结构语句
2.2.1 表字段
添加字段:ALTER TABLE users2 ADD id SMALLINT UNSIGNED;
删除字段:ALTER TABLE users2 DROP id ;
要批量操作则在末尾加上“,DROP col_name…”
添加字段到某指定位置:ALTER TABLE users2 ADD id SMALLINT UNSIGNED AFTER 列名(或FIRST,插到开头);
2.2.2 约束
添加主键约束:ALTER TABLE users2 ADD CONSTRAINT PK_users2_id PRIMARY KEY(id);
添加唯一约束:ALTER TABLE users2 ADD UNIQUE (username);
添加外键约束: ALTER TABLE users2 ADD FOREIGN KEY (pid) REFERENCES provinces(id);
添加删除默认约束: ALTER TABLE users2 ALTER age SET DEFAULT 15; ALTER TABLE users2 ALTER age DROP DEFAULT;
删除主键约束: ALTER TABLE users2 DROP PRIMARY KEY;
删除唯一约束:ALTER TABLE users2 DROP INDEX(KEY) index_name;
删除外键约束:ALTER TABLE users2 DROP FOREIGN KEY users2_ibfk_1;
2.2.3 列
修改列定义:ALTER TABLE tab_name MODIFY [COLUMN] col_name column_definition [FIRST|AFTER col_name];
举例: ALTER TABLE users2 MODIFY id SMALLINT UNSIGNED NOT NULL FIRST;(此时可对数据类型修改,由大范围变小会导致某些数据丢失)
修改列名称:ALTER TABLE tab_name CHANGE [COLUMN] old_col_name new_col_name column_definition [FIRST|AFTER col_name];
2.2.4 修改表名
(1)ALTER TABLE tab_name RENAME [AS|TO] new_tab_name(单次更名)
(2)RENAME TABLE tab_name TO new_tab_name[,tab_name2 TO new_tab_name2…];(批量更名)
注意:列名,表名可能被其他引用或创建了索引,改名后可能会导致视图,存储过程无法正常工作,慎用!!!
INSERT:
UPDATE
DELETE
SELECT
4.1子查询简介
子查询是指出现在其他SQL语句中的SELECT 子句。
例如:SELECT * FROM t1 WHERE col1=(SELECT col2 FROM t2);其中SELECT * FROM t1称为Outer Query/Outer Statement,SELECT col2 FROM t2称为子查询;
4.2 使用子查询
4.2.1 使用比较符 = ,>,<,>=,<=,!=,<>,<=>
如: SELECT * FROM tdb_goods WHERE goods_price>=(SELECT ROUND(AVG(goods_price),2) FROM tdb_goods);
4.2.2用ANY,SOME,ALL修饰比较符,用于比较子查询返回的多条数据时,ANY与SOME等价,只要满足一条数据,ALL要满足所有数据。
如:SELECT goods_name FROM tdb_goods WHERE goods_price >= ALL(SELECT goods_price FROM tdb_goods WHERE goods_cate =’超极本’);
4.2.3使用[NOT] IN的子查询
=ANY与IN等价
!=ALL或<>ALL与NOT IN等价
4.2.4 将查询结果写入数据表
INSERT [INTO] tab_name [(col_name,…)] SELECT…
如: INSERT tdb_goods_cates(cate_name) SELECT goods_cate FROM tdb_goods GROUPBY goods_cate;
4.3多表更新
UPDATE table-references SET col_name1={expr1|DEFAULT}[,col_name2={expr2|DEFAULT}]…[WHERE where_condition]
4.4多表更新之一步更新(将创建表,查询结果写入新建表,多表更新合成一步)
第一步,第二步合为一步:
CREATE TABLE [IF NOT EXISTS] tab_name[(create_definition,…)] select_statement
如:
CREATE TABLE tdb_goods_brands (brand_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,brand_name VARCHAR(40) NOT NULL)
SELECT brand_name FROM tdb_goods GROUP BY brand_name;
第三步:
UPDATE tdb_goods AS g INNER JOIN tdb_goods_brands AS b ON g.brand_name = b.brand_name
SET g.brand_name = b.brand_id;
(由于两表有同名字段brand_name,不能像之前那样直接=)
4.3连接
table_references{[INNER|CROSS]JOIN|{LEFT|RIGHT[OUTER]JOIN}table_references ON conditional_expr
当conditional_expr中两表比较的字段重名,则可设别名
(1)table_references tab_name [[AS] alias]|table_subquery [AS] alias
数据表可以使用tab_name AS alias_name或tab_name alias_name赋予别名,见上
(2)table_subquery可以作为子查询使用在FORM字句中,这样的子查询必须为其赋予
连接分为:
(1)内连接,显示左右表符合连接条件的记录
(2)左连接,显示左表全部记录和右表符合连接条件的记录
(3)右连接,显示右表全部记录和左表符合连接条件的记录
多表连接
如:SELECT goods_id,goods_name,cate_name,brand_name,goods_price FROM tdb_goods AS g INNER JOIN tdb_goods_cates AS c ON g.cate_id=c.cate_id INNER JOIN tdb_goods_brands AS b ON g.brand_id=b.brand_id;
关于连接的几点说明:
? A LEFT JOIN B join_condition
? 如果使用内连接查找的记录在连接数据表中部存在,并且在WHERE子句中尝试一下操作:col_name IS NULL时,如果col_name被定义为NOT NULL,MySQL将在找到符合连接条件的记录后停止搜索更多的行。
4.4无限极分类表设计
(1)无限分类的数据表设计
CREATE TABLE tdb_goods_types(type_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,type_name VARCHAR(20) NOT NULL, parent_id SMALLINT UNSIGNED NOT NULL DEFAULT 0);
插入数据后:
(2)查找所有分类及其父类
SELECT s.type_id,s.type_name,p.type_name
FROM tdb_goods_types
AS s LEFT JOIN tdb_goods_types AS p
ON s.parent_id = p.type_id;
s.parent_id = p.type_id的顺序可变,LEFT JOIN左右顺序绝对不能变,表示显示哪张表的全部,要显示全的字段用左表.xx
4.5多表删除
删除重复数据中id较大的
DELETE t1 FROM tdb_goods
AS t1 LEFT JOIN (SELECT goods_id,goods_name FROM tdb_goods GROUP BY goods_name HAVING count(goods_name) >= 2 )
AS t2 ON t1.goods_name = t2.goods_name
WHERE t1.goods_id > t2.goods_id;
由于做过纸质笔记,暂时不再介绍,可直接百度
自定义函数的必要条件:
1.参数
2.返回值
函数都有返回值,不一定有参数
基本语句:
CREATE FUNCTION function_name RETURNS {STRING|INTEGER|REAL|DECIMAL} routine_body
routine_body——>函数体
复合结构可以包括声明,循环,控制结构
如:CREATE FUNCTION f1() RETURNS VARCHAR(30) RETURN DATE_FORMAT(NOW(),’%Y年%m月%d日%H点:%i分:%s秒’);
为什么我直接SELECT DATE_FORMAT(…)返回正确,SELECT f1()返回结果里:和中文变成了?号 视频里f1()返回正确!!!
创建具有复合结构函数体的函数(以插入数据为例)
错误示范:
CREATE FUNCTION adduser(username VARCHAR(20)) RETURNS INT UNSIGNED RETURN INSERT test(username) VALUES(username);
因为insert返回的结果根本不是int型
正确示范:
1.DELIMITER // (修改分隔符;为//,其他均可)
2.把LAST_INSERT_ID()作为返回值
3.由于此时有insert语句和LAST_INSERT_ID()函数,需要用复合结构
4.最终语句如下:
CREATE FUNCTION adduser(username VARCHAR(20))
RETURNS INT UNSIGNED
BEGIN
INSERT test(username) VALUES(username) ;
RETURN LAST_INSERT_ID() ;
END //
**ps:注意这两个;号,缺一不可,且只能用;号**
删除自定义函数
DROP FUNCTION [IF_EXISTS] fun_name
6.1 什么是存储过程和如何创建
SQL命令执行流程:
SQL指令——>MySQL引擎_分析_>语法正确——>可识别命令_执行_>执行结果_返回_>客户端
Mysql储存过程是一组为了完成特定功能的SQL语句集,经过编译之后存储在数据库中,当需要使用该组SQL语句时用户只需要通过指定储存过程的名字并给定参数就可以调用执行它,从而省去分析语法等步骤,提高效率
语句:
CREATE [DEFINER={user|CURRENT_USER}]
PROCEDURE sp_name([proc_parameter[,…]])
[characteristic…]routine_body
其中proc_parameter–>[IN|OUT|INOUT] param_name type
IN,表示该参数的值必须在调用存储过程时指定
OUT,表示该参数的值可以被存储过程改变,并且可以返回
INOUT,表示该参数的值在调用存储过程时指定,并且可以被改变和返回
过程体:
举例:
创建存储过程:
CREATE PROCEDURE spl() SELECT VERSION();
使用:
CALL spl;或者CALL spl();(由于创建的时候没有指定参数,所以两种方法均可,如果指定了参数,必须第二种)
6.2创建带有IN类型参数的存储过程
DELIMITER //
CREATE PROCEDURE removeUserById(IN id INT UNSIGNED)
BEGIN
DELETE FROM users WHERE id=id;
END//
CALL removeUserById(1);
注意:我们的本意是删除users表中id=1的记录,但结果是记录全被删除,这是因为我们设置的参数和id字段重名,在WHERE语句中,左边id是字段名,右边id是条数,但系统会误认为两边id都是字段名!!!
修改:
(1) DROP PROCEDURE removeUserById;(删除存储过程)
(2)重复上面操作,修改参数名不为id即可
6.3创建带有IN,OUT类型参数的存储过程
由于要用到MySQL变量,做下简单介绍:
mysql变量的术语分类:
1.用户变量:以”@”开始,形式为”@变量名”
用户变量跟mysql客户端是绑定的,设置的变量,只对当前用户使用的客户端生效
2.全局变量:定义时,以如下两种形式出现,set GLOBAL 变量名 或者 set @@global.变量名
对所有客户端生效。只有具有super权限才可以设置全局变量
3.会话变量:只对连接的客户端有效。
4.局部变量:作用范围在begin到end语句块之间。在该语句块里设置的变量
declare语句专门用于定义局部变量。set语句是设置不同类型的变量,包括会话变量和全局变量
CREATE PROCEDURE p8 ()
BEGIN
DECLARE a INT;
DECLARE b INT;
SET a = 5;
SET b = 5;
INSERT INTO t VALUES (a);
SELECT s1 * a FROM t WHERE s1 >= b;
END; //
以创建删除指定行数,返回剩余行数的存储过程为例:
CREATE PROCEDURE removeUserAndReturnUserNums(IN p_id INT UNSIGNED,OUT userNum INT UNSIGNED)
BEGIN
DELETE FROM users WHERE _id=p_id;
SELECT count(_id) FROM users INTO userNum;
END//
CALL removeUserAndReturnUserNums(1,@nums);
SELECT @nums;
6.4创建带有多个OUT类型参数的存储过程
用到ROW_COUNT()函数,返回上一操作影响的记录条数
以创建删除指定记录,并返回删除记录数和剩余记录数的存储过程为例
DELIMITER //
CREATE PROCEDURE removeUserByNameAndReturnInfos(IN p_name VARCHAR(10) ,OUT deleteUsers SMALLINT UNSIGNED,OUT userCounts SMALLINT UNSIGNED)
BEGIN
DELETE FROM test WHERE username=p_name;
SELECT ROW_COUNT() INTO deleteUsers;
SELECT COUNT(id) FROM test INTO userCounts;
END
//
DELIMITER ;
CALL removeUserByNameAndReturnInfos(‘a‘,@a,@b);
SELECT @a,@b;
+------+------+
| @a | @b |
+------+------+
| 1 | 7 |
+------+------+
//表中有8条记录,只有1条username=a
6.5存储过程与自定义函数的区别
实际开发中函数用的比较少,存储过程用的更多
MySQL可以将数据以不同的技术存储在文件(内存)中,这种技术称为存储引擎。
每一种存储引擎使用不同的存储机制、索引技巧、锁定水平,最终提供广泛且不同的功能。
先介绍几个名词:
MySQL支持的存储引擎:
修改存储引擎的方法
通过修改mysql配置文件实现,5.5以上默认InnoDB
-default-storage-engine=engine
通过创建数据表命令实现
-CREATE TABLE table_name(
…
)ENGINE=engine;
由于数据库实战里用到Navicat,具体操作还请自行百度
我的MySQL数据库学习笔记
标签:left join 数据类型 并发控制 两种 sso 区别 全局 get 查看