数据的基本操作
MySQL的存储引擎
- MySQL属于数据库管理系统,接口负责管理数据库。由于不同用户对数据的容量、访问速度、数据安全性有不同的要求,为了满足不同用户的业务需求,MySQL数据库采用多种存储引擎进行数据存储。
- 存储引擎制定了表的存储类型,即如何存储和索引数据、是否支持事物等,同时存储引擎也决定了表在计算机中的存储方式。MySQL5.5支持的存储引擎有InnoDB、MyISAM、MEMORY、MRG_MyISAM、ARCHIVE、FEDERATED、CSV、BLACKHOLE、PERFORMANCE_SCHEMA共九种,可以使用SHOW ENGINES语句查看系统所支持的引擎类型。
-
常用的存储引擎
-
不同的数据引擎有不同的特点,以适应不同的需求,以下重点介绍两种常用的存储引擎InnoDB和MyISAM ,为了做出选择需要对比它们所提供的功能
功能 InnoDB MyISAM 支持事物 支持 不支持 支持全文索引 不支持 支持 外键约束 支持 不支持 表空间大小 较大 较小 数据行锁定 支持 不支持 -
InnoDB和M有ISAM各自的使用场合如下:
- MyISAM存储引擎:该存储引擎不支持事物,也不支持外键约束,访问速度比较快。因此不需要事物处理,以访问为主的应用适合使用该引擎。
- InnoDB存储引擎:该存储引擎在事务处理上有优势(事物处理相关内容在第五章讲解),即支持具有提交、回滚和崩溃恢复能力的事物控制,所以比MyISAM引擎占用更多的磁盘空间。因此对需要进行频繁的更新、删除操作,同时还对事物的完整性要求比较高,需要实现并发控制的应用,适合使用该存储引擎。
-
-
操作默认存储引擎
-
MySQL 5.5以上版本默认的存储引擎是InnoDB,通过以下语句来查看当前默认的存储引擎:
SHOW VARIABLES LIKE 'storage_engine%'; #其中,LIKE后要查询的关键字为'storage_engine%',表示查询默认存储引擎 #如需修改默认存储引擎,可以通过配置向导,也可以通过修改配置文件my.ini来实现。修改配置文件my.ini时 #,只需修改以下内容 defaulstorage-engine=InnoDB; #如果想让修改后的参数生效,必须重新启动MySQL服务
-
-
指定表的存储引擎
-
数据表默认使用当前MySQL默认的存储引擎,有时为了达到数据表的特殊功能要求,也可重新设置表的存储类型。语法格式如下。
CREATE TABLE 表名( #省略代码 )ENGINE=存储引擎; #例如 CREATE TABLE myisam( id INT(4) )ENGINE=MyISAM;
-
-
MySQL 的数据文件
5内容详见书本第51页... ...
插入数据记录
-
插入单行数据语法格式如下
INSERT INTO 表名[(字段名列表)] VALUES(值列表);
表的字段是可选的,如果省略,则依次插入所有字段。
多个列表和多个值之间使用逗号分隔。
值列表必须和字段名列表数量相同,且数据类型相符。
-
如果插入的时表中部分列的数据,字段名列表必须填写。
#例如向student表中插入一条记录 INSERT INTO student(loginPWB,studentName,gradeId,gradeId,phone,birthday) VALUES(123,'黄小苹',1,13956799999,1996-5-8);
-
插入多行数据语法格式如下
- MySQL中的INSERT语句支持一次插入多条记录,插入时可指定多个值列表,每个值列表之间用逗号分隔。
INSERT INTO 新表(字段名列表) VALUES (值列表1),(值列表2),......,(值列表n); #例如 INSERT INTO subject(subjectName,classHour,gradeId) VALUES(logic,Java,220,1),(HTML,160,1),(Java OOP,230,2);
注意:在使用INSERT语句插入记录时,如果不包含字段名称,VALUES关键字后面的值列表中个字段的顺序必须和表定义中的顺序相同,如果表结构变了(如执行了添加字段操作),则值列表也要变化,否则会出现错误。如果制定了插入的字段名,就会避免这个问题,因此建议在插入数据时指定具体的字段名。
-
将查询结果插入到新表中,语法格式入下
-
CREATE TABLE 新表 (SELECT 字段1,字段2,... ... FROM 原表);
CREATE TABLE 'phoneList'(SELECT studentName,'phone'FROM student);
-
更新数据记录
- 语法格式:UPDATE 表名 SET 列名=更新值 [WHERE 更新条件]
- SET后面可以紧随多个“列名=更新值”以修改多个数据列的值,不限一个,不同列之间使用逗号分隔。
- WHERE子句是可选的,用来限制更新数据的条件。若不限制,则整个表的所有数据行将被更新。
- 需要注意的是,使用UPDATE语句可能更新一行数据,也可能更新更多行数据,还可能不会更新任何数据。
删除数据记录
-
使用DELETE删除数据
-
使用SQL语句删除表中的数据,语法格式如下
-
DELETE FROM 表名 WHERE 删除条件
DELETE FROM student WHERE studentName='王宝宝';
还有一种情况,如果删除的行的主键值被其他表引用,MySQL将报告约束冲突的错误信息。
注意:DELETE语句删除的是整体条记录,不会只删除单个列,所以在DELETE后不能出现列名,否则MySQL将报告错误信息。
-
-
-
使用TRUNCATE TABLE删除数据
- TRUNCATE TABLE 用来删除表中的所有行,功能上类似于没有WHERE子句的DELETE 语句。但TRUNCATE TABLE 比DELETE执行速度块,使用的系统资源和事物日志资源更少,并且删除数据后表的数据标识列会重新开始i编号。
- 注意:TRUNCATE TABLE会删除表中的所有行,但表的机构、列、约束、索引等不会被改动。TRUNCATE TABLE不能用于有外键约束的表,这种情况下,需要使用DELETE语句。
- 实际工作中不建议使用TRUNCATE TABLE语句,因为使用它删除的数据不能恢复。
数据查询语句
- 使用SELECT语句,最简单的查询语句的语法格式如下
SELECT <列名|表达式|函数|常量>FROM<表名>[WHERE<查询条件表达式> ] [ORDER BY<排序的列名>[ASC或DESC]]
其中,WHERE条件是可选的,若不限制,则查询返回所有行的数据。
-
注意:在查询语句中还可以使用很多其他的关键字来实现其他特殊的要求。有关SELECT语句的详细语法请参考MySQL帮助文档和教程
注意:查询语句可以分为多个子句,例如,上面的查询语法可以划分为 SELECT...FROM...WHERE... ORDER BY四个子句,对于复杂的SQL语句,可以将每个子句单独写成一行,以方便调试和查找错误
-
查询所有的数据行和列
- 把表中所有行和列都列举出来比较简单,这时候可以使用“*”标识所有的列,例如:SELECT * FROM student
-
查询部分行和列
-
查询部分列需要列举不同的列名,而查询部分行需要使用WHERE子句进行条件限制
SELECT studentNo,studentName,address FROM student WHERE address='河南新乡' #以上的查询语句将只查询地址为'河南新乡'的学生,并且只显示学生编号、姓名和地址。同理,以下语句 #用来查询地址不是“河南新乡”的学生信息 SELECT studentNo,studentName,address FROM student WHERE address <>'河南新乡'
-
-
在查询中使用列的别名
AS子句可以用来改变结果集中列的名称,也可以为组合或者计算出的列指定名称,还有一种情况是让标题列更容易懂,例如,在查询studentNo列并将列名显示为“学生编号”。
-
在SQL中重新命名列名可以使用AS子句,例如:
SELECT studentNo AS 学生编号,studentName AS 学生姓名,address AS 学生地址 FROM student WHERE address<>'河南新乡'
-
还有一种情况是为通过计算、合并得到的新列命名。例如,假设在某数据库的雇员表employee中存在firstName列和lastName类,现在需要将这两列合并为一个叫做“姓名”的列,可以使用以下查询语句
SELECT firstName+'.'+lastName AS 姓名 FROM employee
-
-
查询空值
-
在SQL语句中采用“IS NULL"或者“IS NOT NULL”来判断值是否为空
SELECT studentName FROM student WHERE email IS NULL
-
-
在查询中使用常量列
-
有时候,需要将一些常量的默认信息添加到查询输出结果中,以方便统计或计算
SELECT studentName AS 姓名,address AS 地址,'北京新兴桥' AS 学校名称 FROM student;
-
-
常用函数
MySQL中的函数将一些常用的处理数据的操作封装起来,这样大大简化了程序员的工作,提高了开发效率。因此,除了会使用SQL语句之外,还需要掌握一些常用函数。
-
聚合函数
函数名 作用 AVG() 返回某字段的平均值 COUNT() 返回某字段的行数 MAX() 返回某字段的最大值 MIN() 返回某字段的最小值 SUM() 返回某字段的和 -
字符串函数
函数名 作用 举例 CONTACT(str1,...,strn) 连接字符串str1,...,strn为一个完整的字符串 SELECT CONCAT('My','S','QL');返回:MySQL INSERT(str,pos,len,newsstr) 将字符串str从pos位置开始,len个字符长的字串替换为字符串newstr SELECT INTSERT('这是MySQL数据库',3,10,'MySQL');返回:这是MySQL LOWER(str) 将字符串str中的所有字符变为小写 SELECT LOWER('MySQL');返回:mysql UPPER(str) 将字符串str中的所有字符变为大写 SELECT UPPER('MySQL');返回:MYSQL SUBSTRING(str,num,len) 返回字符串str中第num个位置开始长度为len的字符串 SELECT SUBSTRING('JavaMySQL',5,5);返回:MySQL -
如果需求中规定学员信工的首字母必须大写,可采用UPPER(str)函数实现,SQL语句如下
SELECT UPPER(studentName) FROM student;
+ 时间日期函数 + 除了聚合函数和字符串函数之外,日期函数也是一类常用函数。 | 函数名 | 作用 | 举例(部分结果与当前日期有关) | | :-------------------: | :------------------------------------: | :-------------------------------------------------: | | CURDATE() | 获取当前日期 | SELECT CURDATE();返回:2017-08-08 | | CURTIME() | 获取当前时间 | SELECT CURTIME();返回:19:19:26 | | NOW() | 获取当前日期和时间 | SELECT NOW();返回:2017-08-08 19:19:26 | | WEEK(date) | 返回一个date为一年中的第几周 | SELECT WEEK(NOW());返回:26 | | YEAR(date) | 返回date的年份 | SELECT YEAR(NOW());返回:2017 | | HOUR(time) | 返回时间time的小时值 | SELECT HOUR(NOW());返回:9 | | MINUTE(time) | 返回时间time的分钟值 | SELECT MINUTE(NOW());返回:43 | | DATEDIFF(date1,date2) | 返回日期参数date1和date2之间相隔的天数 | SELECT DATEDIFF(NOW(),'2008-8-8');返回:3247 | | ADDDATE(date,n) | 计算日期参数date加上n天后的日期 | SELECT ADDDATE(NOW(),5);返回:2017-09-02 09:37:07 | 如果需求中规定要对学员的出生年份进行统计,采用YEAR(date)函数的SQL语句如下 ```mysql SELECT YEAR(birthday) FROM student; ``` + 数学函数 + 在使用SQL语句进行数据操作时,优势也会需要进行数值运算,MySQL支持的常用数学函如下 | 函数名 | 作用 | 举例 | | :------: | :---------------------------: | :------------------------------------: | | CEIL(x) | 返回大于或等于数值x的最小整数 | SELECT CEIL(2.3);返回:3 | | FLOOR(x) | 返回小于或等于数值x的最大整数 | SELECT FLOOR(2.3);返回:2 | | RAND() | 返回0~1之间的随机数 | SELECT RAND();返回:0.5525468583708134 |
-
ORDER BY子句
-
如果需要按照一定顺序排列查询结果,则需要使用ORDER BY子句,并且排序可以是升序(ASC)或者降序(DESC)。如果不指定ASC或者DESC,结果集默认按ASC升序排序。
SELECT studentID AS 学生编号,(studentResult*0.9+5) AS 综合成绩 FROM result WHERE(studentResult*0.9+5)>60 ORDER BY studentResult #还可以按照多个列进行排序。例如,要在学生排序的基础上,再按照课程ID进行排序 SELECT studentID AS 学生编号,courseID AS 课程编号,studentResult AS 成绩 FROM result WHERE studentResult>60 ORDER BY studentResult,coutseID
注意,按照多个列进行排序时,每列之间使用逗号分隔,并且可再每列后面设置排序的升降序,例如:ORDER BY 列1ASC,列2DESC
-
-
LIMIT子句
- 在实际开发中,可能要求显示指定位置指定行数的记录。下面介绍如何通过DQL语句限制查询出的数据的位置和数目。语法格式如下
- SELECT <字段名列表> FROM <表名或视图> [WHERE <查询条件>] [GROUP BY<排序的列名>[ASC或DESC]] [LIMIT[位置偏移量],行数]。
- 位置偏移量指从结果集中第几条数据开始显示(第一条记录的位置偏移量是0,第二条是1.....),此参数可选,当省略默认从第一条记录开始显示。
- 行数指显示记录的条数。2
- LIMIT子句可以实现数据的分页查询,即从一批结果数据中规定每页显示多少条数据,也可以查询中间某页记录。LIMIT子句经常与ORDER BY子句一起使用,即先对查询结果进行排序,然后根据LIMIT的参数显示其中部分数据。
- 在实际开发中,可能要求显示指定位置指定行数的记录。下面介绍如何通过DQL语句限制查询出的数据的位置和数目。语法格式如下
-
子查询在WHERE语句中的一般用法如下
- SELECT... ... FROM 表1 WHERE 字段1 比较运算符(子查询);
- 其中,子查询语句必须放置在一对圆括号内,比较运算符包括>、=、<、>=、<=.
- 习惯上,外层铲鲟称为夫查询,圆括号中嵌入的查询称为子查询。SQL语句执行时,先执行子查询部分,求出子查询部分的值,再执行整个父查询,返回最后的结果。
- 子查询作为WHERE条件的一部分,还可以和UPDATE、INSERT、DELETE一起使用,语法类似于SELCET语句。
- 注意:将子查询和比较运算符联合使用,必须保证子查询返回的值不能多余一个。
- 注意:SELECT语句使用SELECT * FROM 'student'语句的执行效率会低于SELECT 'studentNo','studentName','sex','birthday','address' FROM 'student',因为前者获得表中所有字段所占用的资源将大于后者获得的指定字段所占资源。另外,后者的可维护性高于前者。因此,再编写查询语句时,建议大家采用这样的格式:SELECT 字段列表 FROM 表名 WHERE 条件表达式
- SELECT... ... FROM 表1 WHERE 字段1 比较运算符(子查询);
-
IN子查询
- 使用IN关键字可以使父查询匹配子查询返回的多个单字段值
- 使用=、>等比较运算符时,要求子查询只能返回一条或空的记录。在MySQL中,当子查询跟随在=、!=、<、<=、>和>=之后时,不允许子查询返回多条记录。
- 出错信息"Syvqyert returns more than 1 row"的意思是“子查询返回值不唯一”。如要返回多条 只需将“=”改为“IN”即可,“IN”后面的子查询 可以返回多条记录。有“IN”子查询 同理 相反也有“NOT IN ”子查询