数据类型
1> 整数类型
(1)指定类型显示宽度:数据类型(显示宽度)
如:INT(4)
(2)ZEROFILL 属性:用于数据不足的显示空间由0来填补,
可以大量用于所谓“流水号”的生成上
如:CREATE TABLE
t1(id
INT
(6) ZEROFILL AUTO_INCREMENT PRIMARY KEY
,col2 VARCHAR
(32));
(3)AUTO_INCREMENT 属性:是字段成为自增字段
(4)UNSIGNED 属性:将整型转换成无符号的
如:id int(4) unsigned zerofill NOT NULL
2> 浮点数类型和定点数类型
(1)指定浮点数和定点数的精度:数据类型(M,D) M参数的精度数,就是数据的长度 D参数的表弟,就是小数点后的长度
如:FLOAT(6,2)
3> 日期与时间类型
(1)YEAR以YYYY的形式显示年份
注:使用2位字符串表示,如:00 或 "00" 会转换成 2000
(2)TIME以D HH:MM:SS形式存储,但可以不按照严格方式存储 如:HH:MM
(3)CURRENT_TIME 或 NOW() 表示当前系统时间
(4)DATE以YYYY-MM-DD 形式存储,支持不严格语法如YYYY/MM/DD YYYY@MM@DD YYYY.MM.DD 会自动转换成 YYYY-MM-DD 格式
(5)DATETIME以YYYY-MM-DD HH:MM:SS 形式存储
注:DATETIME只能使用NOW()来传递当前系统时间
(6)TIMESTAMP也是以YYYY-MM-DD HH:MM:SS 形式存储,但是其范围比DATETIME要小
注:使用CURRENT_TIMESTAMP 或 NULL 或 无任何输入,系统会输入当前系统时间
4> 字符串类型
包括 CHAR、VARCHAR、BLOB、TEXT、ENUM、SET
注:<1> 存储路劲“\”会被系统过滤掉,需要转义成 “\\”或“/”
<2> MySQL存储BOOLEAN或BOOL其最终会转换成TINYINT(1)存储
<3> MySQL一般不存储图片和音频文件而是存储路劲,要是要存储就是用BLOB
(1)CHAR 和 VARCHAR
都是在创建表时指定最大长度,形式:字符串类型(M) M最大长度
VARCHAR是在范围内长度可变用多少分配多少因此资源利用率高,而CHAR始终占用指定长度的空间有点费空间但是查询效率比VARCHAR快很多,因此CHAR适用于作主键 或 存储固定长度字符串数据 或 频繁修改数据
(2)TEXT
用于存储大量的文字信息,占用资源大,谨慎使用。各种TEXT类型仅仅在于存储数据多少的差异
(3)ENUM
以列表的形式指定,形式为
属性名 ENUM('value1','value2',...) 只能取其中一个
注:若加上NOT NULL则默认取列表中第一个元素
(4)SET
以列表的形式指定,形式为
属性名 SET('value1','value2',...) 可取一个或多个,不同元素之间用逗号隔开,插入数据时系统会按照定义顺序显示,如:插入 ('C','B','D') 数据库中以 B,C,D 形式保存
5> 二进制类型
6> BOOLEAN类型
BOOLEAN值时用1代表TRUE,0代表FALSE,boolean在MySQL里的类型为tinyint(1),四个常量:true,false,TRUE,FALSE,它们分别代表1,0,1,0
如:insert into test(isOk) values(true);
操作数据库
1> 数据库登录
dos窗口连接数据库
mysql -h localhost -u root -p 在输入密码
2> 数据库创建、删除、查询操作
(1)创建数据库
CREATE DATABASE 数据库名;
(2)显示系统中所有的数据库
SHOW DATABASES;
(3)删除数据库
DROPDATABASE 数据库名;
注:删除数据库指令将会删除数据库中所有的数据和表
(4)使用数据库
USE 数据库名称;
3> 存储引擎
(1)查询系统中支持的存储引擎
SHOW ENGINES;
注:<1> Engine属性指存储引擎名称,Support属性指是否支持该类型YES表示支持NO表示不支持DEFAULT表示默认,Comment属性指对该引擎的评论,Transactions属性指是否支持事务处理,XA属性指是否分布式处理XA规范,Savepoints属性指是否支持保存点以便回滚到保存点
<2> 一般使用默认 InnoDB 就可以
(2)常用的存储引擎
4> 表的创建、修改、删除
(1)创建表
CRETAE TABLE 表名(属性名 数据类型 [完整性约束条件],...)
(2)完整性约束
<1> 单子段主键:
属性名 数据类型 PRIMARYKEY KEY 如:
CREATE TABLE T1(id INTEGER PRIMARY KEY,name VARCHAR(20));
多字段主键:
PRIMARY KEY(属性名1,属性名2,...) 如:CREATE TABLE T1(id INTEGER,name VARCHAR(20),PRIMARY KEY(id,name));
<2> 表的外键(必须依赖于父表的主键,期可以为空):
CONSTRAINT 外键别名 FOREIGN KEY(属性名1.1,属性名1.2,...) REFERENCES 表名(属性名2.1,属性名2.2,...)
如:CREATE TABLE T1(id INTEGER PRIMARY KEY,name VARCHAR(20),CONSTRAINT c_fk FOREIGN KEY(id) REFERENCES T2(id));
<3> 非空约束:
属性名 数据类型 NOT NULL
<4> 唯一性约束:
属性名 数据类型 UNIQUE
<5> 自动增长(主要用于为新纪录生成唯一ID且一个表只有一个AUTO_INCREMENT约束并是主键的一部分其是任何整数类型):
属性名 数据类型 AUTO_INCREMENT
<6> 默认值:
属性名 数据类型 DEFAULT 默认值
(3)查看表结构:
<1> 表基本结构:
DESCRIBE 表名;
<2> 表详细结构:
SHOW CREATE TABLE 表名;
(4)修改表
<1> 修改表名:
ALTER TABLE 旧表名 RENAME [TO] 新表名;
<2> 修改数据类型:
ALTER TABLE 表名 MODIFY 属性名 数据类型;
<3> 修改字段名:
ALTER TABLE 表名 CHANGE 旧属性名 新属性名 新数据类型;
<4> 增加字段:
ALTER TABLE 表名 ADD 属性名1 数据类型 [完整性约束] [FIRST|AFTER 属性名];
<5> 删除字段:
ALTER TABLE 表名 DROP 属性名;
<6> 修改存储引擎:
ALTER TABLE 表名 ENGINE=存储引擎名
(5)删除表
<1> 没有关联的普通表:
DROP TABLE 表名;
<2> 有关联的父表:先删除关联表外键约束
ALTER TABLE 表名 DROP FOREIGN KEY 外键名 再删除表
5> 事务,事务是一个最小的、不可分割的工作单元,不论成功与否都作为一个整体进行工作,其具有Atomic(原子性),Consistent(一致性),Isolated(隔离性),Durable(持久性)
START TRANSACTION;
// 提交事务
COMMIT;
// 回滚
ROLLBACK;
索引
用于快速查询数据库表中的数据
优点:提高检索数据的速度
缺点:索引需要占用物理空间,因此在增加、删除、修改数据时会造成维护速度降低
1> 索引的设计原则
(1)选择唯一性索引,可更快通过索引确定某条记录
(2)为经常需要排序ORDER BY、分组GROUP BY和联合操作UNION的字段建立索引
(3)为常作为查询条件的字段建立索引
(4)限制索引的数目,索引太多需要的磁盘空间就越大,修改表示对索引的重构和更新会很麻烦
(5)尽量使用数据量少的索引,对CHAR(100)全文索引肯定会比CHAR(10)耗时多
(6)尽量使用前缀来索引
(7)删除不再使用或者很少使用的索引
2> 创建索引
创建表时创建索引,其最基本形式是
CREATE TABLE 表名(属性名 数据类型 [完整性约束条件],属性名 数据类型 [完整性约束条件]... 属性名 数据类型 [UNIQUE|FULLTEXT|SPATIAL] INDEX|KEY [别名] (属性名1 [(长度)] [ASC|DESC])) FULLTEXT是可选参数表示全文索引,SPATIAL是可选参数表示空间索引,INDEX和KEY指定那些字段是索引二择其一作用相同
(1)创建普通索引:如:CREATE TABLE T1(id INT,name VARCHAR(50),INDEX(id))
(2)创建唯一性索引:如:CREATE TABLE T1(id INT UNIQUE,name VARCHAR(50),INDEX(id ASC))
(3)创建全文索引:全文索引只建立在CHAR、VARCHAR或TEXT类型的字段上,且只有MyISAM存储支持全文索引 如:CREATE TABLE T1(id INT,name VARCHAR(50),FULLTEXT INDEX(name
))
(4)创建单列索引:在单个字段上的一部分建立索引只查询前面若干索引 如:CREATE TABLE T1(id INT,name VARCHAR(50),INDEX(name(10)))
(5)创建多列索引:在表的多个字段上创建一个索引 如:CREATE TABLE T1(id INT,name VARCHAR(50),INDEX(id,name))
注:只有在使用索引中的第一个字段时才会触发索引
(6)创建空间索引:
(7)在已存在的表上创建索引:
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX 索引名 ON 表名 (属性名 [(长度)] [ASC|DESC])
(8)用ALTER TABLE语句来创建索引:
ALTER TABLE 表名 ADD [UNIQUE|FULLTEXT|SPATIAL] INDEX 索引名 ON 表名 (属性名 [(长度)] [ASC|DESC])
如:ALTER TABLE Info_Pictures ADD INDEX pictures_index_userId(picturesUserId, picturesCreatetime ASC)
3> 删除索引
基本形式是
DROP INDEX 索引名 ON 表名
视图
视图是一种虚拟的表由一个或多个表导出,其可以从已存在的视图基础上定义,数据库中只存放视图的定义没有存放视图中的数据,数据依旧在原来的表中。使用视图时会从原来的标中取出对应的数据,因此视图中的数据依赖于原来的表中的数据,一旦表中的数据发生变化,显示在视图中的数据也会发生变化
1> 创建视图
语法形式:
CREATE [ALGORITHM={UNDEFINED|MERGE|TEMPTABLE}] VIEW 视图名 [(属性清单)] AS SELECT 语句 [WITH [CASCADED|LOCAL] CHECK OPTION] ALGORITHM为可选参数表示视图选择的算法其包括3个选项UNDEFINED(自动选所使用的算法)、MERGE(使用视图语句与视图定义结合起来使得视图定义的某一部分取代语句对应部分)、TEMPTABLE(将视图的结果存入临时表再使用零时表执行语句),WITH CHECK OPTION是可选参数表示更新视图时要保证在该视图的权限范围内
注:创建视图时,最好加上WITH CHECK OPTION 和 CASCADED,这样从视图派生出来的新视图后,更新新视图需要考虑其父视图的约束条件
(1)单表创建视图:如:CREATE VIEW v1 AS SELECT * FROM t1;
(2)多表创建视图:如:CREATE ALGORITHM=MERGE VIEW v1(name,age) AS SELECT name,age FROM t1,t2 WITH LOCLA CHECH OPTION;
2> 修改视图
语法形式:
CREATE OR REPLACE [ALGORITHM={UNDEFINED|MERGE|TEMPTABLE}] VIEW 视图名 [(属性清单)] AS SELECT 语句 [WITH [CASCADED|LOCAL] CHECK OPTION]
或是使用ALERT语句
ALTER
[ALGORITHM={UNDEFINED|MERGE|TEMPTABLE}] VIEW 视图名 [(属性清单)] AS SELECT 语句 [WITH [CASCADED|LOCAL] CHECK OPTION]
注:只要有权限,更新视图中的信息,对应的表中数据也将更新
无法更新视图的情况
(1)视图中包含SUN()、COUNT()、MAX()、MIN()等函数
(2)视图中包含UNION、UNION ALL、DISTINCT、GROUP BY、HAVING
(3)常亮视图
(4)视图中包含SELECT子查询
(5)由不可更新的试图导出的视图
(6)创建视图时,ALGORITHM为TEMPTABLE
3> 删除视图
语法形式:
DROP VIEW [IF EXISTS] 视图名 [RESTRICT|CASCADE]
触发器
触发器是由INSERT、UPDATE、DELETE语句触发
1> 创建只有一个执行语句的触发器,语法形式:
CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件 ON 表名 FOR EACH ROW 执行语句; BEFORE指在触发事件之前执行触发语句,AFTER在触发事件之后执行语句,触发事件指触发条件可以是INSERT、UPDATE、DELETE,表名指触发事件操作的表的名称,FOR EACH ROW表示任何一条记录上的操作满足触发事件都会触发该触发器,执行语句指触发器被触发后执行的程序 如:CREATE TRIGGER trigger1 BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO time VALUES(NOW());
2> 创建多个执行语句的触发器,语法形式:
CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件 ON 表名 FOR EACH ROW BEGIN 所有执行语句 END
注:1> 一般系统以“;”作为执行语句,在创建触发器过程中需要用到“;”,可以使用DELIMITER语句防止多条执行语句结尾的“;”导致提前执行触发器,如:
DELIMITER
&&
CREATE TRIGGER trigger1 AFTER DELETE ON t1 FOR EACH ROW
BEGIN
INSERT INTO t2(time) VALUES(NOW());
INSERT INTO t3(time) VALUES(NOW());
END
&&
DELIMITER;
2> 同一个表在相同触发事件的相同触发事件,只能创建一个触发器,像是同一个表可创建INSERT事件的BEFORE和AFTER事件
3> 显示触发器,语法形式:
SHOW TRIGGERS;
4> 触发器的执行顺序是BEFORE触发器、表操作(INSERT、UPDATE和DELETE)和AFTER触发器
5> 触发器中不能包含START TRANSACTION、COMMIT、CLAA或ROLLBACK的关键词,触发器在执行过程中任何步骤出错都会组织程序向下执行,对于普通表已更新过的记录不能回滚,更新后的数据将继续保持在表中
6> 删除触发器,语法形式:
DROP TRIGGER 触发器名;
查询数据
1> 基本查询语句,语法形式:
SELECT 属性列表 FROM 表名和视图列表 [WHERE 条件表达式1] [GROUP BY 属性名1 [HAVING 条件表达式2]] [ORDER BY 属性名2 [ASC|DESC]]
(1)语法规则:
[NOT] IN(元素1,元素2,...)
(2)语法规则:
[NOT] BETWEEN 取值1 AND 取值2 如:SELECT * FROM t1 WHERE age BETWEEN 15 AND 25;
(3)语法规则:
[NOT] LIKE '字符串' “%”代表任意长度的字符串,“_”代表单个字符串
(4)语法规则:
IS [NOT] NULL 如:SELECT * FROM t1 WHERE column1 IS NULL;
(5)AND 同时满足多条查询条件,OR 满足其中一条查询条件
(6)查询结果不重复,语法规则:
SELECT DISTINCT 属性名 如:SELECT DISTINCT column1 FROM t1;
(7)语法规则:
ORDER BY 属性名 [ASC|DESC]
(8)分组查询,语法规则:
GROUP BY 属性名 [HAVING 条件表达式] [WITH ROLLUP] WITH ROLLUP关键字会在所有记录的最后加上一条记录,记录所有记录的总和,GROUP BY关键字通常与几何函数一起使用COUNT()统计记录总数、SUM()计算字段的值的综合、AVG()计算字段值的平均值、MAX()查询字段的最大值、MIN()查询字段的最小值、GROUP_CONCAT()将分组中指定字段值都显示出来,如:SELECT GROUP_CONCAT(name) FROM t1 GROUP BY sex; 返回的数据是 name1,name2,name3
注:1> {1,2,3}就是升序,{3,2,1}就是降序,默认是ASC
2> *是所有字段
2> LIMIT限制查询结果数量
(1)不指定初始化位置,从第一条记录开始显示指定条数记录,语法规则:
LIMIT 记录数 如:SELECT * FROM t1 LIMIT 2;
(2)指定初始化位置,位置基于0,语法规则:
LIMIT 初始位置,记录数
如:SELECT * FROM t1 LIMIT 0,2;
SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15
SELECT * FROM table LIMIT 95,-1; // 为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:检索记录行 96-last
SELECT * FROM table LIMIT 5; // 如果只给定一个参数,它表示返回最大的记录行数目,换句话说,LIMIT n 等价于 LIMIT 0,n:检索前 5 个记录行
3> 连接查询
(1)内连接查询,如:SELECT a.name,b.name FROM t1,t2 WHERE t1.id=t2.id;
(2)外链接查询,语法规则:
SELECT 属性名列表 FROM 表名1 LEFT|RIGHT JOIN 表名2 ON 表名1.属性=表名2.属性;
4> 子查询
(1)带IN关键字的子查询,如:SELECT * FROM t2 WHERE column1 IN(SELECT column1 FROM t2)
(2)带比较运算符的子查询,如:SELECT * FROM t2 WHERE column1>=(SELECT
column1 FROM t2)
(3)带EXISTS的子查询,如:SELECT * FROM t2 WHERE EXISTS(SELECT
column1 FROM t2)
(4)带ANY关键字的子查询,ANY关键字表示满足其中任一条件,如:SELECT * FROM t2 WHERE column1>=ANY(SELECT
column1 FROM t2)
(5)带ALL关键字的子查询,ALL关键字表示满足所有条件,如:SELECT * FROM t2 WHERE column1>=ALL(SELECT
column1 FROM t2)
5> 合并查询结果
语法规则:
SELECT 语句1 UNION|UNION ALL SELECT 语句2 UNION|UNION ALL...
如:SELECT id FROM t1 UNION SELECT id FROM t2
注:UNION关键字会将所有查询出的结果合并到一起,再去除所有相同记录,而UNION ALL 则可能存在相同记录
6> 位字段取别名
语法规则:
属性名 [AS] 别名
7> 正则表达式查询,语法规则:
属性名 REGEXP '匹配方式'
插入、更新与删除数据
1> 插入数据
(1)不指定具体字段名,语法规则:
INSERT INTO 表名 VALUES(值1,值2...)
(2)指定具体字段名,语法规则:
INSERT INTO 表名(属性1,属性2...) VALUES(值1,值2...)
(3)同时插入多条数据,语法规则:
INSERT INTO 表名[(属性列表)] VALUES(值列表1),(值列表2)...
(4)将查询结果插入到表中,语法规则:
INSERT INTO 表名1(属性列表1) SELECT 属性列表2 FROM 表名2 WHERE 条件表达式;
2> 更新数据
语法规则:
UPDATE 表名 SET 属性1=值1,... WHERE 条件表达式
3> 删除数据
语法规则:
DELETE FROM 表名 [WHERE 条件表达式]
运算符
1> 算术运算符
如:SELECT a,a+10,a-5 FROM t1
2> 比较运算符
3> 逻辑运算符
4> 位运算符
函数
1> 数学函数
2> 字符串函数
3> 日期时间函数
4> 条件判断函数
(1)IF(expr,v1,v2)函数:如果表达式expr成立返回v1否则返回v2,如:SELECT id,IF(grade>=60,'PASS','FAIL') from t1;
(2)IFNULL(v1,v2)函数:v1不为空则返回v1否则返回v2
(3)CASE函数
<1>
CASE WHEN expr1 THEN v1 [WHEN e2 THEN v2...] [ELSE vn] END CASE表示开始,END表示函数结束,expr1成立返回v1,依次类推,最后ELESE时返回vn
如:SELECT id,grade,CASE WHEN grade>60 THEN 'GOOD' WHEN grade=60 THEN 'PASS' ELSE 'FAIL' END level FROM t6;
<2>
CASE expr WHEN e1 THEN v1 [WHEN e2 THEN v2...] [ELSE vn] END 如果字段expr等于e1返回v1依次类推
如:SELECT id,grade,CASE grad WHEN grade>60 THEN 'GOOD' WHEN grade=60 THEN 'PASS' ELSE 'FAIL' END level FROM t6;
5> 系统信息函数
6> 加密函数
(1)PASSWORD(str):对字符串加密 如:
SELECT PASSWORD('abcde')
(2)MD5(str):MD5对str加密
(3)ENCODE(str,pswd_str):使用字符串pswd_str来加密字符串str,加密结果是二进制数,必须使用BLOB类型保存
(4)DECODE(crypt_str,pswd_str):使用pswd_str来为crypt_str解密
7> 其它函数
(1)FORMAT(x,n):数字x进行格式化,将x保留小数点后n位
存储过程和函数
存储过程和函数是在数据库中定义一些SQL语句的集合,然后直接调用这些存储过程和函数来执行已经定义好的SQL语句。存储过程可以避免开发人员重复的编写相同的SQL语句。而且,存储过程和函数是在MySQL服务器中存储和执行的,可以减少客户端和服务器端的传输数据
1> 创建存储过程:
CREATE PROCEDURE sp_name([proc_parameter[,...]]) [characteristic...] routine_body
sp_name是存储过程名称
proc_parameter是存储过程的参数列表每个参数有3个部分组成分别是输入输出类型、参数名称和参数类型心事如:
[IN|OUT|INOUT] param_name type
characteristic是存储过程的特性
注:系统默认指定CONTAINS SQL,表示使用SQL语句,如果没有使用SQL,最好设置为NO SQL
routine_body是代码的内容,可以用BEGIN...END来标志SQL代码的开始和结束
如:
DELIMITER
&&
CREATE PROCEDURE num_from_employee(IN emp_id INT,OUT count_num INT)
READS SQL DATA
BEGIN
SELECT COUNT(*) INTO count_num
FROM employee WHERE d_id=emp_id;
END
&&
DELIMITER
2> 创建存储函数:CREATE FUNCTION sp_name([func_parameter[,....]]) RETURANS type [characteristic...] routine_body
如:
DELIMITER
&&
CREATE FUNCTION name_from_employee(emp_id INT) RETURNS VARCHAR(20)
BEGIN
RETUEN (SELECT name FROM employee WHERE num=emp_id);
END
&&
DELIMITER
3> 变量使用
(1)定义变量,语法规则:
DECLARE var_name[,...] type [DEFAULT value] DECLARE关键字用来声明变量,var_name是变量名称,type是变量类型,DEFAULT value是默认值没有默认是NULL
如:DECLARE my_sql INT DEFAULT 10;
(2)变量赋值,语法规则:
SET var_name=expr[,var_name=expr]... 如:SET my_sql=30;
SELECT col_name[,...] INTO var_name[,...] FROM table_name WHERE condition 如:SELECT d_id INTO my_sql FROM employee WHERE id=2
5> 流程控制使用
(1)IF语句,基本语法形式:
IF search_condition THEN statement_list
[ELSEIF search_condition THEN statement_list]...
END IF
如:IF age>20 THEN SET @count=@count+1;
ELSEIF age=20 THEN @count2=@count2+1;
ELSE @count3=@count3+1;
END IF;
(2)CASE语句,可以实现比IF语句更复杂的条件判断,语法形式:
CASE case_value
WHEN when_value THEN statement_list
[WHEN when_value THEN statement_list]...
[ELSE statement_list]
END CASE
或是
CASE
WHEN search_value THEN statement_list
[WHEN search_value THEN statement_list]...
[ELSE statement_list]
END CASE
如:CASE age
WHEN 20 THEN SET @count1=@count1+1;
ELSE SET @count2=@count2+1;
END CASE;
或是
CASE
WHEN age=20 THEN SET @count1=@count1+1;
ELSE SET @count2=@count2+1;
END CASE;
(3)LOOP语句,循环执行,必须使用LEAVE停止循环,语法形式:
[begin_label:]LOOP
statement_list
END LOOP [end_label]
如:
add_num:LOOP
SET @count=@count+1;
IF @count=100 THEN LEAVE ad_num;
END LOOP add_num;
(4)ITERATE语句:跳出本次循环,进入下一次循环,语法格式:
ITERATE label
如:
add_num:LOOP
SET @count=@count+1;
IF @count=100 THEN LEAVE add_num;
ELSE IF MOD(@count,3)=0 THEN ITERATE add_num;
SELECT * FROM employee;
END LOOP add_num;
(4)REPEADT语句,满足条件时跳出循环语句,语法格式:
[begin_label] REPEAT
statement_list
UNTIL search_condition
END REPEAT [end_label]
如:
REPEAT
SET @count=@count+1;
UNTIL @count=100;
END REPEAT;
(5)WHILE语句,当满足条件执行循环内的语句,语法格式:
[begin_label:] WHILE search_condition DO
statement_list
END WHILE [end_label]
如:
WHILE @count<100 DO
SET @count=@count+1;
END WHILE;
6> 调用存储过程和函数
(1)调用存储过程,系统执行存储过程中的语句,然后将结果返回,基本语法:
CALL sp_name([parameter[,...]])
如:
// 创建存储过程
DELIMITER &&
CASER PROCEDURE num_from_employee(IN emp_id,OUT count_num INT)
READS SQL DATA
BEGIN
SELECT COUNT(*) INTO count_num FROM employee WHERE d_id=emp_id;
END &&
DELIMITER;
// 调用存储过程
CALL num_from_employee(1002,@n);
// 查询返回结果
SELECT @n;
(2)调用存储过程,如:
// 创建存储函数
DELIMITER &&
CREATE FUNCTION name_from_employee(emp_id INT)
RETURNS VARCHAR(20)
BEGIN
RETURN (SELECT name FROM employee WHERE num=emp_id);
END&&
DELIMITER;
// 调用存储过程
SELECT name_from_employee(3);
7> 修改存储过程和函数,语法格式:
ALTER {PROCEDURE|FUNCTION} sp_name[characteristic...] characteristic:
{CONTAINS SQL|NO SQL|READS SQL DATA|MODIFIES SQL DATA}
|SQL SECURITY{DEFINER|INVOKER}
|COMMENT 'string'
如:ALTER FUNCTION name_from_employee READS SQL DATA COMMENT 'find name';
SELECT SPECIFIC_NAME,SQL_DATA_ACCESS,ROUTINE_COMMENT FROM information_schema.Routines WHERE ROUTINE_NAME='name_from_employee';
8> 删除存储过程和函数,语法格式:
DROP {PROCEDURE|FUNCTION} sp_name
注:存储过程的CALL方法可以调用其它的存储过程
用户管理
MySQL包括普通用户和root用户,root用户是超级管理员拥有所有权限
1> 新建用户
(1)创建普通用户,语法格式:
CREATE USER user [IDENTIFIED BY [PASSWORD] 'password'] [,user [IDENTIFIED BY [PASSWORD] 'password']]...
如:CREATE USER 'test1'@'localhost' IDENTIFIED BY
'test1';
2> 删除用户
(1)删除普通用户,语法格式:
DROP USER user [,user]...;
如:DROP USER 'test2'@'localhost';
3> root用户修改自己的密码,语法格式:
mysqladmin -u username -p password "new_password";
注:其中的password为关键字不是指旧密码,而且新密码必须用双引号括起来使用单引号会出现错误,如果使用单引号,可能造成修改后密码不是你想要修改的
如:mysqladmin -u root-p password "myroot1";
4> root用户修改普通用户密码,语法格式:
SET PASSWORD FOR 'username'@'hostname'=PASSWORD("new_password");
注:新密码必须使用PASSWORD()函数加密
如:SET PASSWORD FOR 'test3'@'hostname'=PASSWORD("mytest1");
5> 普通用户修改密码,语法格式:
SET PASSWORD=PASSWORD('new_password');
如:SET PASSWORD=PASSWORD("test")
6> 各种权限
(1)授权,语法格式:
GRANT priv_type [(column_list)] ON database.table TO user [IDENTIFIED BY [PASSWORD] 'password'] [,user [IDENTIFIED BY [PASSWORD] 'password']]... [WITH with_option [with_option]...] priv_type是权限类型,column_list是权限作用于哪些列上没有该参数时作用于整个表上,user是由用户名和主机构成,password是用户新密码
如:GRANT SELECT、UPDATE ON *.* TO 'test5'@'localhost' IDENTIFIED BY 'test5' WITH GRANT OPTION;
7> 回收权限,语法格式:
REVOKE priv_type [(column_list)]... ON database.table FROM user [,user] ...
回收全部权限的语法格式:
REVOKE ALL PRIVILEGES,GRANT OPTION FROM user [,user]...
如:REVOKE UPDATE ON *.* FROM 'test5'@'localhost';
REVOKE
ALL PRIVILEGES,GRANT OPTION FROM 'test5'@'localhost';
8> 查看权限,语法格式:
SELECT * FROM mysql.user;
SHOW GRANTS FOR 'username'@'hostname';
如:SHOW GRANTS FOR 'root'@'localhost'
数据备份和还原
1> 数据库备份,mysqldump命令的工作原理是先查出需要备份的表的结构,再在文本中生成一个CREATE语句,然后将表中的所有记录转换成一条INSERT语句
(1)备份一个数据库,语法格式:
mysqldump -h localhost -u username -p dbname table1 table2 ... > BackupName.sql dbname是数据库的名称,table1和table2是表的名称没有该参数时将备份这个数据库,BackupName.sql表示备份文件的名称可以是绝对路径
注:1> mysqldump命令备份的文件并非一定是.sql也可以是其他格式如.txt,通常是.sql
2> 不登录mysql,直接在MySQL中执行备份语句
如:mysqldump -h localhost -u root -p test student >
D:\T\s.sql
(2)备份多个数据库,语法格式:
mysqldump -h localhost -u username -p --databases dbname1 dbname2 ... > BackupName.sql
(3)备份所有数据库,语法格式:
mysqldump -h localhost -u username -p --all-databases
> BackupName.sql
(4)可以关闭服务器,在将数据库目录复制出来,但是这不是最好的备份方法
2> 使用mysqlhotcopy工具快速备份,这种备份方式mysqldump命令快,工作原理是先将需要备份的数据库加上一个读操作锁,然后用FLUSH TABLES将内存中的数据写回到硬盘上的数据库中,最后被备份的数据库文件复制到目标目录,命令格式如下:
注:1> mysqlhotcopy工具不是MySQL自带的,需要安装Perl的数据库接口报
2
> 由于mysqlhotcopy工具的工作原理是将数据库文件拷贝到目标目录,因此其只能备份MyISAM类型的表,不能用来备份InnoDB类型的表
3> 数据还原,语法规则:
mysql -u root -p [dbname] < backup.sql
日志
启动日志功能会降低MySQL数据库的执行速度,且会占用大量磁盘空间和使用很多内存,一般不开启MySQL数据库的日志功能
1> 二进制日志:以二进制文件形式记录数据库中的操作,但不记录查询语句
2> 错误日志:记录 MySQL 服务器的启动、关闭和运行错误等信息
3> 通用查询日志:记录用户登录和记录查询的信息
4> 慢查询日志:记录执行时间超过指定时间的操作
性能优化
查询系统性能,语法格式:
SHOW STATUS LIKE 'value'; value参数的几个统计参数如下:
1> 分析查询语句
EXPLAIN,DESCRIBE用于分析SELECT语句的执行情况,语法规则:
EXPLAIN SELECT 语句;
DESCRIBE SELECT 语句;
返回的查询结果信息:
2> 索引查询
(1)使用 LIKE 关键字查询时,若匹配字符串的第一个字符为“%”时,索引不会被诗音,如果不在第一个位置,索引就会被使用
(2)多列索引是在表的多个字段上创建一个索引,只有查询条件中使用这些字段中第一个字段时,索引才会被使用
(3)查询语句只有 OR 关键字时,若OR前后两个条件的列都是索引时查询中将使用索引,若OR前后有一个条件的列不是索引,那么查询中将不会使用索引
3> 优化子查询:子查询时,系统内层查询语句的查询结果建立一个临时表,然后外层查询语句再在临时表中查询记录,查询完成后撤销掉这些临时表,因此使用连接查询来代替子查询来代替子查询,这是由于连接查询不需要建立临时表,其速度比子查询要快
(1)将字段很多的表分解成多个表:有些表在设计了很多字段,其中有些字段使用频率低,当该表数据量大时,查询数据的速度就会被拖慢,因此将那些使用频率很低的字段放置在另外一个表中(两外一个表可以是 *_extra)
(2)增加中间表:在查询两个表中的几个字段,经常连表查询会降低数据库查询速度,可将这些字段建立一个中间表并将原来那几个表的数据茶如道中间表中,之后使用中间表来进行查询和统计,以此提高查询速度
(3)增加冗余字段:表的规范化程度越高,表与表之间的关系就越多,若经常进行多表连接查询会浪费很多时间,可增加冗余字段的方式来提高查询速度
4> 优化一行数据的查询,若已知查询结果只有一条,在查询语句之后添加 LIMIT 1 可以在数据库引擎会在找到一条数据后停止搜索,而不是继续往后查少下一条符合记录的数据
5> 使用JOIN级联查询时,应该保证两表中JOIN的字段已近建立过索引且类型相同,这样MySQL内部会启动为你优化JOIN的SQL语句的机制,如:如果你要把 DECIMAL 字段和一个 INT 字段Join在一起,MySQL就无法使用它们的索引。对于那些STRING类型,还需要有相同的字符集才行
6> 避免 SELECT * 查询数据,
从数据库里读出越多的数据,那么查询就会变得越慢并且,如果数据库服务器和WEB服务器是两台独立的服务器的话,这还会增加网络传输的负载。
所以,应该养成一个需要什么就取什么的好的习惯
7> 能使用 ENUM 而就不要使用 VARCHAR,ENUM 类型是非常快和紧凑的,实际上ENUM保存的是 TINYINT,但其外表上显示为字符串。这样用这个字段来做一些选项列表变得相当的完美。如果你有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 而不是 VARCHAR
8> 从 PROCEDURE ANALYSE() 取得建议 :
PROCEDURE ANALYSE() 会让 MySQL 帮你去分析你的字段和其实际的数据,并会给你一些有用的建议。只有表中有实际的数据,这些建议才会变得有用,因为要做一些大的决定是需要有数据作为基础
9> 尽可能的使用 NOT NULL:NULL会占用额外的空间且在进行比较的时候会是程序更复杂,其所代表的意义在不同的数据库中会有所不同坑是字符串"Empty"、"NULL"或是NULL,因此尽量使用NOT NULL
10> 把IP地址存成 INT UNSIGNED;如果你用整形来存放,只需要4个字节,并且你可以有定长的字段。而且,这会为你带来查询上的优势,尤其是当你需要使用这样的WHERE条件:IP between ip1 and ip2。
配合使用后面两个函数来转换ip信息:INET_ATON:将IP地址转换成数字型
INET_NTOA:将数字型转换成ip地址
11> 拆分大的 DELETE 或 INSERT 语句:由于DELETE 和 INSERT操作时会锁表的,表一锁住别的操作都无法进行,对于访问量大的网站所积累的进程/线程的延迟会让Web服务Crash,还会使这个服务器挂掉,因此限制一次对数据库数据修改的次数,对DELETE采用LIMT,如:DELETE FROM logs WHERE log_date <= '2009-11-01' LIMIT 1000
12> 越小的列会越快:如果一个表只会有几列罢了(比如说字典表,配置表),那么,我们就没有理由使用 INT 来做主键,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 会更经济一些。如果你不需要记录时间,使用 DATE 要比 DATETIME 好得多
注:需要留够足够的扩展空间,否则日后修改表时会很困难
13> 对表选择正确的存储引擎:
MyISAM:适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好,甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的
InnoDB:是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。他是它支持“行锁” ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务
14> 优化插入记录的速度
(1)禁用索引:插入记录时索引会对插入的记录进行排序,若插入大量数据时,这些排序会降低插入数据的速度,因此在插入大量数据时,先禁用索引,待插入数据完毕再开启索引
禁用索引的语句:
ALTER TABLE 表名 DISABLE KEYS;
重新开启索引的语句:
ALTER TABLE 表名 ENABLE KEYS;
(2)禁用唯一性检查:插入记录时系统会进行唯一性校验,校验会降低插入记录的速度,可以在插入记录之前禁用唯一性检查,待插入数据完毕再开启
禁用唯一性检查的语句:SET UNIQUE_CHECKS=0;
重新开启唯一性检查的语句:SET UNIQUE_CHECKS=1;
(3)优化INSERT语句:当插入多条数据时,通过一条插入语句比分多条插入语句执行效率速度快很多,这是由于减少与数据库之间的连接等操作,因此能使用LOAD DATA INFILE语句比INSERT语句速度快
(4)在事务中进行插入处理,进行一个INSERT操作时,MySQL内部会建立一个事务,在事务内才进行真正插入处理操作。通过使用事务可以减少创建事务的消耗,所有插入都在执行后才进行提交操作,因此采用事务操作可提高插入数据得速度
(5)插入数据是有序的,这样可减少索引的维护成本
注:合并数据+事务+有序数据的方式在数据量达到千万级以上表现依旧是良好,在数据量较大时,有序数据索引定位较为方便,不需要频繁对磁盘进行读写操作,所以可以维持较高的性能
15> 分析表、检查表和优化表
(1)分析表,语法格式:
ANALYZE TABLE 表名1[,表名2,...]; 返回的结果:
(2)检查表,语法格式:
CHECK TABLE 表名1[,表名2...][option]; option参数有5个参数分别是QUICK、FAST、CHANGED、MEDIUM和EXTENDED,这5个参数的执行效率依次降低
注:option选项只对MyISAM类型的表有效,对InnoDB类型的表无效,CHECK TABLE语句在执行过程中会给表加上只读锁
(3)优化表,使用OPTIMIZE TABLE语句来优化表,该语句只对InnoDB和MyISAM类型的表有效,且该语句只能优化VARCHAR、BLOB或TEXT类型的字段,该语句可以消除删除和更新造成的磁盘碎片从而减少空间的浪费,语法格式:
OPTIMIZE TABLE 表名1[,表名2...];
16> 优化MySQL服务器
17> 其他技巧
(1)尽量使用count(*)计算数量:列的偏移 量决定性能,列越靠后,访问的开销越大。由于count(*)的算法与列偏移量无关,所以count(*)最快, count(最后列)最慢