架构话查询语言(Structured Query Language)
DDL 数据定义语言 (dataDefinition Language)
CREATE、ALTER、DROP
DML 数据操作语言 (data Manipulation Language)
SELECT、INSERT、UPDATE、DELETE
DCL 数据控制语言(data Control Language)
GRANT、REVOKE
DQL 数据查询 (data Query Language)
实体分析法、属性综合法 分别称为 自顶向下法和自底向上法
数据库的设计:需求分析和设计、数据库实现与操作
1、列不可分。
2、非主属性依赖于主属性。
3、所有非主键不能依赖于其他非主键。
3.5、BCNF斯科德范式:任何属性不能对主键的子集依赖。
创建数据库
CREATE DATABASE mysql_test;
修改数据库 mysql_test 的默认字符集和校对规则。
ALTER DATABASE mysql_test
->DEFAULT character SET SET gb2312
->DEFAULT collate gb2312_chinese_ci;
删除数据库
DROP DATABASES mytest;
查看数据库
SHOW DATABASES;
创建表
CREATE TABLE customers
->(
-> cust_id INT NOT NULL AUTO_INCREMENT,
-> cust_name CHAR(50) NOT NULL,
-> cust_sex CHAR(1) NOT NULL DEFAULT 0,
-> cust_address CHAR(50) NULL,
-> PRIMARY KEY(cust_id)
->);
向customers表中增加新列。
ALTER TABLE mysql_test.customers
->ADD COLUMN cust_city char(10) NOT NULL DEFAULT 'Wuhan' AFTER cust_sex;
对某一列重命名cust_sex 换成 sex
ALTER TABLE mysql_test.customers
->CHANGE COLUMN cust_sex sex char(1) NULL DEFAULT 'M';
设置默认值
ALTER TABLE mysql_test.customers
->ALTER COLUMN cust_city SET DEFAULT 'Beijing';
修改字符类型 cust_name 修改为长度20,并将此列设置为第一列
ALTER TABLE mysql_test.customers
->MODIFY COLUMN cust_name char(20) FIRST;
删除数据库某一列
ALTER TABLE mysql_test.customers
->DROP COLUMN cust_contact;
RENAME[TO]子句,重命名数据库中的表customers
ALTER TABLE mysql_test.customers
->RENAME TO mysql_test.backup_customers;
重命名backup_customers 表到 customers
RENAME TABLE mysql_test.backup_customers TO mysql_test.customers;
删除表
DROP TABLE XXX;
查看表
SHOW TABLES ;
显示表结构
DESC mysql_test.customers;
索引(INDEX)、唯一性索引(UNIQUE)、主键(PRIMARY KEY)
表customers上,根据姓名的前三个字符ASC创建一个升序索引index_customers
CREATE INDEX index_customers
-> ON mysql_test.customers(cust_name(3) ASC);
在数据库 mysql_test 的表customers 上,根据客户姓名和客户id号创建一个组合索引index_cust。
CREATE INDEX index_cust
ON mysql_test.customers(cust_name,cust_id);
使用 ALTER 创建非唯一索引,取名为 index_seller_name
ALTER TABLE mysql_test.seller
->ADD INDEX index_seller_name(seller_name);
索引的查看
SHOW index;
索引的删除
DROP INDEX index_name ON tb1_name;
删除表中的索引 index_cust
DROP INDEX index_cust ON mysql_test.customers;
ALTER去删除索引
DROP PRIMARY KEY //用于删除表中的主键,由一个表中只有一个主键,也是一个索引。
DROP INDEX //子句用于删除各种类型的索引;
DROP FOREIGN KEY//用于删除外键
例如:删除主键和索引index_customers
ALTER TABLE mysql_test.customers
->DROP PRIMARY KEY,
->DROP INDEX index_customers;
插入数据INSERT
INSERT INTO mysql_test.customers
->VALUES(901,'张三','F','北京市','朝阳区');
插入数据,id自动生成,cust_sex选默认值,cust_contact列的值不确定。
INSERT INTO mysql_test.customers
->VALUES(0,'李四',DAFAULT,'武汉市',NULL)
每个列是按照次序填充的,如果哪一列没有值,需要用NULL去填充,前提是该列运行为空值,虽然简单但是有点危险,最好写的详细一点,例如:
INSERT INTO mysql_test.customers(cust_id,cust_name,cust_sex,cust_address,cust_contact)
->VALUES(0,'李四',DEFAULT,'武汉市',NULL);
INSERT部分值
INSERT INTO mysql_test.coustomers
->SET cust_name='李四',cust_address='武汉市',cust_sex=DEFAULT;
删除数据
DELETE FROM mysql_test.customers
->WHERE cust_name='王五';
修改数据 //可以修改多个值
UPDATE mysql_test.customers
->SET cust_address='武汉市'
->WHERE cust_name='张三';
列的选择
SELECT cust_name,cust_sex,cust_address
->FROM mysql_test.customers;
查询所有信息
SELECT * FROM mysql_test.customers;
查询特定的列,并将结果使用别名输出
SELECT cust_name,cust_address AS 地址,cust_contact
->FROM mysql_test.customer;
查询值
SELECT cust_name,cust_sex,cust_id+100
->FROM mysql_test.customers;
from子句与多表链接查询
交叉连接
SELECT * FROM tbl1 CROSS JOIN tbl2;
查询WHERE 、IN、BETWEEN
查找id在902~912之间的十个客户的信息。
SELECT * FROM mysql_test.customers
WHERE cust_id BETWEEN 903 AND 912;
使用IN枚举
SELECT * FROM mysql_test.customers
WHERE cust_id IN(903,906,908);
IS判断
SELECT cust_name FROM mysql_test.customers
->WHERE cust_contact IS NULL;
子查询,联查
查询任意成绩高于80分的学生的学号和姓名信息。
SELECT studentNo,studentName
->FROM tb_student
->WHERE studentNo IN (SELECT studentNo FROM tb_score WHERE score>80);
查数据并列出数量
SELECT cust_address,cust_sex,COUNT(*) AS '人数'
->FROM mysql_test,customers
->GROUP BY cust_address,cust_sex;
order by排序
默认将空值作为最小值来对待。
如果是降序,则会将空值放在最下面
升降/ASC/DESC
例如
SELECT cust_name,cust_sex FROM mysql_test.customers
ORDER BY cust_name DESC,cust_address DESC;
LIMIT
从第5位开始选择3个
SELECT cust_id,cust_name FROM mysql_test.customers
->ORDER BY cust_id
->LIMIT 4,3;
SELECT cust_id,cust_name FROM mysql_test.customers
->ORDER BY cust_id
->LIMIT 3 OFFSET 4;
视图
创建名称为customers_view的视图
with check option保证了通过视图进行的修改,必须也能通过该视图看到修改后的结果
CREATE OR REPLACE VIEW mysql_test.customers_view
->AS
->SELECT * FROM mysql_test.customers
-> WHERE cust_sex='M'
-> WITH CHECK OPTION;
WITH CHECK OPTION的作用?
1.对于update,有with check option,要保证update后,数据要被视图查询出来;
2.对于delete,有无with check option都一样;
3.对于insert,有with check option,要保证insert后,数据要被视图查询出来;
4.对于没有where 子句的视图,使用with check option是多余的。
删除 DROP
DROP VIEW [IF EXISTS] view_name[,view_name]
修改视图
ALTERVIEW view_name [(column_list)]
AS select_statement
[WITH]
查看视图
SHOW CREATE VIEW view_name
使用INSERT插入数据
必须创建时候使用了WITH CHECK OPTION
INSERT INTO mysql_test.customers_view
->VALUES(909,'周明','M','武汉市','洪山区')
使用UPDATE通过视图修改基本表的数据
UPDATE mysql_test.customers_view
->SET cust_address='上海市';
DELETE
DELETE FROM mysql_test.customers_view
->WHERE cust_name='周明';
设置mysql的结尾从;变成$$
DELIMITER $$
游标
声明游标
DECLARE cursor_name CURSOR FOR select_statement
打开游标
OPEN cursor_name
读取数据
FETCH cursor_name INTO var_name [,var_name] ***
关闭游标
CLOSE cursor_name
声明局部变量
//DECLARE var_name type;
DECLARE cid INT(10);
SET语句
//SET var_name = expr [,var_name = expr] ...
SET cid = 910;
SELECT_INTO 语句
SELECT col_name[,***] INTO var_name[,***] table_expr
创建存储过程
存储过程是为了完成一组特定功能的SQL语句的集合。
1.增强了灵活性。2.良好的封装性。3.高性能。4.可减少网络流量。5.存储过程可作为一种安全机制来确保数据库的安全性和数据的完整性。
存储过程的优点有哪些
1.更快的执行速度:存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度;
2.与事务的结合,提供更好的解决方案:当对数据库进行复杂操作时(如对多个表进行Update、Insert、Query和Delete时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用;
3.支持代码重用:存储过程可以重复使用,可减少数据库开发人员的工作量;
4.安全性高:可设定只有某此用户才具有对指定存储过程的使用权。
1.增强了灵活性。2.良好的封装性。3.高性能。4.可减少网络流量。5.存储过程可作为一种安全机制来确保数据库的安全性和数据的完整性。
输入、输出、输入/输出
IN、OUT、INOUT
修改表customers 的数据
根据ID修改性别
>USE mysql_test
>DELIMITER $$
>CREATE PROCEDURE sp_name(IN cid INT,IN csex CHAR(1) )
->BEGIN
-> UPDATE customers SET cust_sex=csex WHERE cust_id=cid;
->END $$
CALL调用存储过程
修改客户id为909的,值改为M
>CALL sp_name(909,'M');
删除存储过程
DROP PROCEDURE sp_update_sex;
创建一个计算表中数据行的过程
>USE mysql_test;
>DELIMITER $$
>CREATE PROCEDURE sp_sumofrow(OUT ROWS INT)
->BEGIN
-> DECLARE cid INT;
-> DECLARE FOUND BOOLEAN DEFAULT TRUE;
-> DECLARE cur_cid CURSOR FOR
-> SELECT cust_id FROM customers;
-> DECLARE CONTINUE HANDLER FOR NOT FOUND
-> SELECT FOUND=FALSE;
-> SET ROWS = 0;
-> OPEN cur_cid;
-> FETCH cur_cid INTO cid;
-> WHILE FOUND DO
-> SET ROWS=ROWS+1;
-> FETCH cur_cid INTO cid;
-> END WHILE;
-> CLOSE cur_cid;
->END$$
>CALL sp_sumfrow(@row);
>SELECT @rows;
存储函数
USE mysql_test;
DELIMITER $$
CREATE FUNCTION fn_search(cid INT)
-> RETURNS CHAR(2)
-> DETERMINISTIC
->BEGIN
-> DECLARE SEX CHAR(2);
-> SELECT cust_sex INTO SEX FROM customers
-> WHERE cust_id=cid;
-> IF SEX IS NULL THEN
-> RETURN(SELECT '没有该客户')
-> ELSE IF SEX ='F' THEN
-> RETURN(SELECT '女');
-> ELSE RETURN(SELECT '男'):
-> END IF;
-> END IF;
->END $$
调用存储函数
SELECT fn_search(904);
删除存储函数
DROP FUNCTION IF EXISTS fn_search;
CREATE TRIGGER trigger_name [BEFORE/AFTER] [INSERT/UPDATE/DELETE]
ON tal_name FOR EACH ROW trigger_body
//tal_name必须是永久表,不能是临时表
//FOR EACH ROE 表示对每一行都操作
//body 执行主体
一个@是用户变量
CREATE TRIGGER mysql_test.customers_insert_trigger AFTER INSERT
-> ON mysql_test.customers FOR EACH ROW SET @str='one customers added!'
INSERT INTO mysql_test.customers
-> VALUES(NULL,'万华','F','长沙市','芙蓉区');
删除触发器
>DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name
>DROP TRIGGER IF EXISTS mysql_test.customers_insert_trigger;
注:当删除一个表时,也会删除上面的触发器。
使用触发器
将str变量变成新加入表的cust_id
CREATE TRIGGER mysql_test.customers_insert_trigger AFTER INSERT
>ON mysql_test.customers FOR EACH ROW SET @str=NEW.cust_id;
验证
INSERT INTO mysql_test.customers
>VALUES(NULL,'曾为','F','长沙市','芙蓉区');
SELECT @str;
UPDATE触发器
当触发器对自身进行更新操作时,只能使用BEFORE UPDATE触发器
OLD的值全部是只读的,不能被更新,来访问被删除的行
CREATE TRIGGER mysql_test.customers_update_trigger BEFORE UPDATE
-> ON mysql_test.customers FOR EACH ROW
-> SET NEW.cust_address = OLD.cust_contact;
验证
UPDATE mysql_test.customers SET cust_address='武汉市'
-> WHERE cust_name='曾伟';
SELECT cust_address FROM mysql_test.customers
->WHERE cust_name='曾伟';
结果为芙蓉区
创建用户
CREATE USER user[IDENTIFIED BY [PASSWORD] 'password']
user指定用户账号,格式为‘user_name’@‘host_name’
如果没指定主机名,默认是%
PASSWORD是可选项,选择散列口令,如果使用明文,则可以省略次选项。
可以使用命令获取散列值
获取密码456的散列值
PASSWORD<456>
>********************
创建两个用户
CREATE USER 'zhangsan'@'localhost' IDENTIFIED BY '123',
->'list'@'localhost' IDENTIFIED BY PASSWORD
->'******';
删除用户
DROP USER list@localhost;
修改用户账号
RENAME USER old_user TO new_user
RENAME USER 'zhangsan'@'localhost' TO 'wangwu'@'localhost';
修改密码
SET PASSWORD FOR 'wangwu'@'localhost'
->='****************';
查看用户的授权表
SHOW GRANT FOR 'ZHANGSAN'@'localhost';
权限的授予
GRANT
priv_type[(column_list)]
[,priv_type[(column_list)]]...
ON[object_type]priv_level
TO user_specification[,user_specification]
[WITH GRANT OPTION]
1.priv_type 用于指定权限的名称
2.可选语法项"column_list" 用于指定权限要授予给表中哪些具体的列
3.ON子句用于指定权限的对象和级别,例如给出数据库名或表名
4.type用于指定类型,例如 “TABLE”、“FUNCTION”、“PROCEDURE”
5.level 用于指定权限 ,例如 * 就是当前数据库中的所有表,"*.*” 就是所有数据库中的所有表
6.TO 用于指定被授予权限的用户
7.后面可以接具体描述
例如:
授权用户zhangsan 在数据库 mysql_test 的表 customers 上拥有对列cust_id 和列cust_name 的 SELECT 权限。
GRANT SELECT(cust_id,cust_name)
-> ON mysql_test.customers
-> TO 'zhangsan'@'localhost';
不能执行SELECT * ,否则会报错
创建两个用户,并授予相关的权限。
GRANT SELECT,UPDATE
-> ON mysql_test.customers
-> TO 'limit'@'localhost' IDENTIFIED BY '123',
-> 'huang'@'localhost' IDENTIFIED BY '789';
授权所有可以执行的权限
GRANT ALL
->ON mysql_test.*
->TO 'wangwu'@'localhost';
授予可创建用户的权限
GRANT CREATE USER
-> ON *.*
-> TO 'wangwu'@'localhost';
创建一个用户zhou ,并授予他select和update权限去操作coustomers表
并允许其将自身权限授权给别人。
GRANT SELECT,UPDATE
-> ON mysql_test.customers
-> TO 'zhou'@'localhost' IDENTIFIED BY '123'
-> WITH GRANT OPTION;
权限的撤销
REVOKE ALL PRIVILEGES,GRANT OPTION FROM user
拥有CREATE权限,才能执行REVOKE
REVOKE SELECT
-> ON mysql_test.customers
-> FROM 'zhou'@'localhost';