过程化语言
非过程化语言
DDL数据定义语言
DML数据操纵语言
DCL数据控制语言
交互式SQL 比如MySQL的终端工具
嵌入式SQL SQL被嵌入到其他的高级语言中
查询语句
select 字段名称 from 数据表 where 查询条件
对表的操作:
create table
drop table
alter table
grant 用于授予用户的访问权限
revoke 用于接触用户访问权限
支持的数据类型
整数
- TINYINT 使用一个字节,也就是八位来存储
- SMALLINT 使用两个字节,也就是十六位来存储
- MEDIUMINT 三个字节,24位
- INT 四个字节,32位
- BIGINT 八个字节,64位存储
实数 带有小数部分的数字
MySQL支持精确类型的实数,也支持不精确类型的实数。
支持使用标准的浮点数运算,也就是不精确的类型。
- FLOAT 四个字节,32位
- DOUBLE 八个字节,64位
- 可以指定精度,但是精度都是非标准的,建议是只指定数据类型,不要指定精度。
- DECIMAL 用于存储精确的小数。还能指定小数点之后的位数。
DECIMAL(20,2)小数点后两位,前18位
字符串类型的数据 在数据库中用的是最多的。
- VARCHAR 保存可变长度的字符串,只规定最大长度值,系统根据实际存储的数据量分配存储空间。
- CHAR 固定长度的字符串,长度范围0-255任意值,
- TEXT
- TINYTEXT
- TEXT
- MEDIUMTEXT
- LOGTEXT
- BLOB 和text类型类似
text列一般被看作是非二进制字符串,即字符字符串,有自己的字符集,
blob列一般被看做是二进制字符串,即字节字符串,没有字符集,排序和比较都是基于字节的。
datetime 用八个字节进行存储
TIMESTAMP 时间戳类型,4个字节存储,1970-2038
选择数据类型的原则:
- 最小原则,应该尽量使用可以存储数据的尽可能小的数据类型
- 简单原则,计算机处理,尽量使用MySQL自带的东西
- 避免索引列上的NULL,MySQL默认的是可以为NULL,最好指定为not null。
sql语句中的查询,如果需要同时满足两个条件都满足的内容,要用and。
更新一个表的数据,
update 表名 set 字段 = 值 where 查询条件
更新列的名字:
alter table 表名 change 原列名 新列名 新列存储数据的类型
在一个表中按照一定的条件查找:
首先是要查找的内容同时符合两个及其以上的条件。
select * from 表名 where 条件1 and 条件二 and 条件三…
接下来是查找的内容符合查找条件的一个就行
select * from 表名 where 条件1 or 条件2 or 条件3…
接下来是查找的内容符合其中的一个条件,并且不符合另一个条件:
select * from 表名 where 字段=条件1 and 字段!=条件2
- 数据库(Database):数据库是带有相关数据的表的集合。
- 表(Table):表是带有数据的矩阵。数据库中的表就像一种简单的电子表格。
- 列(Column):每一列(数据元素)都包含着同种类型的数据,比如邮编。
- 行(Row):行(又被称为元组、项或记录)是一组相关数据,比如有关订阅量的数据。
- 冗余(Redundancy):存储两次数据,以便使系统更快速。
- 主键(Primary Key):主键是唯一的。同一张表中不允许出现同样两个键值。一个键值只对应着一行。
- 外键(Foreign Key):用于连接两张表。
- 复合键(Compound Key):复合键(又称组合键)是一种由多列组成的键,因为一列并不足以确定唯一性。
- 索引(Index):它在数据库中的作用就像书后的索引一样。
- 引用完整性(Referential Integrity):用来确保外键一直指向已存在的一行。
向表格中添加一列,并设置成自增的整形数,并且设置该字段位这个表格的主键。
创建数据库的时候
主要的工作,一个是为项目设计表,另一个是使用SQL语句。
其余的都可以使用相关的工具。
多种方式可以连接到mysql,其中本地连接一般用socket,我的DELL的Socket路径是/var/run/mysqld/mysqld.sock
还可以远程连接,使用 mysql -h IP地址 -P 端口(默认是3306) - uroot -p 敲回车之后会提示你输入密码。然后就连接上了。
socket权限一般是777,不要随便修改,修改之后就连不上MySQL了。socket是个空文件,不要删除。一旦删除了就要重启mysql,才能恢复。
不要把密码输入到命令行里,存在安全的风险。
表中每一行被称为记录,每一列被称为字段。
常见的SQL语言:
- DDL,数据定义,比如创建,修改和删除表。
- DML,数据操作,对表内的数据进行增删改查。
- DCL,权限管理,
- TCL,事务相关操作。
如何搭建测试环境
过滤查询
- 比较运算符,常见的 =(等于), !=(不等于), >, <, >=, <=
- 逻辑运算符,与或非
- 优先级,比较运算符优先级最高,接下来是not,接下来是and,接下来是or
范围查询,也就是使用between…and..,使用来查询某一个值域范围的记录,常用在数字类型数据的范围上,但是字符类的数据和日期类的数据也可以用。
集合查询,使用in运算符,来判断列的值是否在指定的集合中。
空值查询,我么可以使用is null判断列的值是否为空。
模糊查询,Like,直接举例子:
匹配的时候%是通配符,表示零或者多个字符;
_通配符,但是只能表示一个字符;
drop table 表名 在数据库里直接删除表和表中的信息。
tips:删除的时候如果一个记录中的某个字段为空,如果使用
这个操作达不到目的,因为这个操作中的筛选条件是记录中的字段有值,是个字符串“null”,所以没有找到空值去确定要删除的记录。
这个语句可以达到目的,因为这样的筛选条件才是筛选对应字段为空值的记录。
SQL语句对于大小写是不敏感的。
关于外键的问题,首先要设置外键。假设字段1是表b中的字段,要想使1成为a的外键,那么对字段1要建立索引,如果1恰好是表b的主键,那么他自然就有索引,如果1不是表b的唯一的主键,那么要对字段1添加索引之后,字段1才能作为表a的外键,那么如何为字段创建索引呢?举例说明
alter table table_name add index 字段名称 (字段名称
);
建表之后设置主键:
alter table table_name add primary key (主键字段);
建表之后设置外键:
alter table tablename add constraint fk外键字段名 foreign key (外键字段名) references 外键所在表名称(外键字段名称);
如何对查询结果去除重复呢?使用关键字distinct,还是举例说明:
如何添加主键和外键
https://zhidao.baidu.com/question/159936267.html
如何表示浮点数:
http://www.2cto.com/database/201411/350899.html
如何表示时间和日期的格式:
http://www.jb51.net/article/55853.htm
索引相关:
http://www.cnblogs.com/tianhuilove/archive/2011/09/05/2167795.html
可以在select语句的筛选条件中使用算术运算符,但是使用的结果不会影响原来的表中的数据,因为select只是查询,不能更改,可以尝试用update语句来更改数据。
但是有一个问题就是not这个取反的标识符,有的时候放在字段的后面是可以的,但是有的时候需要放在字段的前面,不知道到底在什么位置是合适的。
select where 语句中也是允许使用逻辑运算符的,比如与(and),或(or),非(not);
多表查询,首先是确定外键,
关于链接关键字join,sql的join有三种,分别是内连接,外连接和交叉连接。
- 内连接,只显示出两个表按照join条件连接起来的信息,其他信息是不显示的。1234567891011121314151617mysql> select name,building from instructor as a inner join department as b on a.dept_name = b.dept_name;+--------------+-----------------+| name | building |+--------------+-----------------+| 康辉 | 梨园楼 || 谭永杰 | 机械大厦 || 陈军 | 第一教学馆 || 黄文鹏 | 材料馆 || 尼格买提 | 建艺大厦 || 文静 | 数学馆 || 朱广全 | 化工楼 || 欧阳夏丹 | 红楼 || 王可爱 | 运动大厦 || 邱慧 | 法律大厦 || 易信 | 八角楼 |+--------------+-----------------+11 rows in set (0.23 sec)
在这里内部连接使用的命令上面使用where子句的命令的结果是一样的,但是呢,要注意join连接的命令的格式,格式是这样的:
select 字段1, 字段2… form tableA inner join tableB on tableA.字段 = tableB.字段;
这里还能使用as关键字,用于指代某个表,方面后面的操作。
- 接下来是外连接,左外连接left outer join = left join 显示左表的所有的记录,以及右表中符合join的条件的信息,不符合的置空。下面是参考的例子:1234567891011121314151617181920212223mysql> select building,name from department as a left outer join instructor as b on a.dept_name = b.dept_name;+-----------------+--------------+| building | name |+-----------------+--------------+| 八角楼 | 易信 || 化工楼 | 朱广全 || 声乐楼 | NULL || 建艺大厦 | 尼格买提 || 摩根楼 | NULL || 摩根楼 | NULL || 数学馆 | 文静 || 机械大厦 | 谭永杰 || 材料馆 | 黄文鹏 || 梨园楼 | 康辉 || 法律大厦 | 邱慧 || 演艺中心 | NULL || 第一教学馆 | 陈军 || 红楼 | 欧阳夏丹 || 计算机楼 | NULL || 语言大厦 | NULL || 运动大厦 | 王可爱 || 通信大楼 | NULL |+-----------------+--------------+
同样右外连接和左外连接相反,举例子:
在这里left outer join 和 left join是一样的。
全外连接,full outer join = full join,左右两个表的信息全部显示,不符合的置空。
报错了,是为什么呢?明显是外键的问题,在网上查资料,有的说是表名和mysql的保留字冲突了,但是我的命名没有问题啊。
是在不是很清楚是什么原因,先放下晚上问问别人。
那还有个问题,就是不写什么内容直接用join的时候代表的是什么呢?个人理解是代表的inner join。
- 还有一种就是cross join,概念:没有 WHERE 子句的交叉联接将产生联接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。(table1和table2交叉连接产生3*3=9条记录)。12345678910111213mysql> select * from instructor as a cross join department as b;+----------+--------------+--------------+--------+--------------+-----------------+----------+| id | name | dept_name | salary | dept_name | building | budget |+----------+--------------+--------------+--------+--------------+-----------------+----------+| 20000065 | 康辉 | 戏曲系 | 30000 | 中文系 | 红楼 | 12000000 || 20000401 | 谭永杰 | 机械系 | 9800 | 中文系 | 红楼 | 12000000 || 20012029 | 陈军 | 工商管理 | 20000 | 中文系 | 红楼 | 12000000 || 20019823 | 汪峰 | 音乐系 | 40000 | 中文系 | 红楼 | 12000000 |...| 20160129 | 易信 | 农业系 | 9800 | 音乐系 | 声乐楼 | 3600000 || 20172888 | 徐行 | 会计学 | 14300 | 音乐系 | 声乐楼 | 3600000 |+----------+--------------+--------------+--------+--------------+-----------------+----------+324 rows in set (0.07 sec)
结果是两个表的笛卡尔积,这里因为两个表每个表各有18行记录,得到的结果是18x18=324行。
接下来看排序的关键字order by,分为升序排列,关键词asc,这也是order by 默认的序列,降序排列加关键词desc。
在以上的结果中有两个相等的公司名称 (W3School)。只有这一次,在第一列中有相同的值时,第二列是以升序排列的。如果第一列中有些值为 nulls 时,情况也是这样的。
上面的对比不是很明显,下面的更加明显
这个里面中文的排序规则就真的不是很清楚是怎样的一个规则了,晚上可以查一下。
删除某一行,delete from table_name where 字段=值。
限制我们查询得到的行数,也就是取查询结果的一部分,使用limit关键词。
top和precent关键字实验没有成功,晚上自己回去查相关的资料。
通配符:
通配符 | 描述 |
---|---|
% | 替代一个或多个字符 |
_ | 仅替代一个字符 |
[charlist] | 字符列中的任何单一字符 |
[^charlist]或者[!charlist] | 不在字符列中的任何单一字符 |
[charlist]这个并不是很清楚为什么没成功。一个同事说[charlist]只支持sqlserver和另一个也是微软开发的数据库
接下开是union,UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。
union会自动过滤重复的结果,如果有重复的记录但是不想过滤都显示出来要用union all
SELECT INTO 语句
SELECT INTO 语句从一个表中选取数据,然后把数据插入另一个表中。
SELECT INTO 语句常用于创建表的备份复件或者用于对记录进行存档。
但是实际操作中呢,这个语句不是很清楚要怎么做,可以以后查相关的资料。
MySQL中的日期和时间:
MySQL Date 函数
下面的表格列出了 MySQL 中最重要的内建日期函数:
函数 描述
NOW() 返回当前的日期和时间
CURDATE() 返回当前的日期
CURTIME() 返回当前的时间
DATE() 提取日期或日期/时间表达式的日期部分
EXTRACT() 返回日期/时间按的单独部分
DATE_ADD() 给日期添加指定的时间间隔
DATE_SUB() 从日期减去指定的时间间隔
DATEDIFF() 返回两个日期之间的天数
DATE_FORMAT() 用不同的格式显示日期/时间
reference link: http://www.w3school.com.cn/sql/sql_dates.asp
mysql中的ifnull()函数和coalesce()函数。
数据类型:
http://www.w3school.com.cn/sql/sql_datatypes.asp
关于SQL函数
合计函数(aggregate functions):
常见的有:
- avg(列名): 计算某一列中所有数据的平均值。
- count(列名):计算某一列得行数。
- count(*)返回被选的行数
- first(列名):返回在指定的域中的第一个记录的值。经过实践证明,这个函数在MySQL中是不好用的。
- last(列名):返回在指定域中的最后一个值。经过实践证明,这个函数在MySQL中是不好用的。
- max(列名):返回某列中的最大的值。
- min(列名):但会某列中最小的值。
group by用于结合合计函数,根据一个和多个列对结果进行分组。
1234567891011121314151617181920212223242526272829303132333435363738394041mysql> select * from classroom;+--------------+-------------+----------+| building | room_number | capacity |+--------------+-------------+----------+| 化工楼 | 312 | 100 || 声乐楼 | 东21 | 10 || 声乐楼 | 西11 | 40 || 建艺大厦 | 621 | 100 || 数学馆 | 202 | 20 || 数学馆 | 403 | 120 || 机械大厦 | M10 | 200 || 梨园楼 | 301 | 20 || 梨园楼 | 501 | 20 || 红楼 | a-201 | 200 || 红楼 | a-301 | 200 || 红楼 | b-101 | 150 || 计算机楼 | a-420 | 70 || 计算机楼 | b-305 | 240 || 语言大厦 | A-008 | 50 || 语言大厦 | B-201 | 500 || 通信大楼 | 1003 | 300 || 通信大楼 | 2001 | 300 |+--------------+-------------+----------+18 rows in set (0.00 sec)mysql> select building, count(room_number) from classroom group by building;+--------------+--------------------+| building | count(room_number) |+--------------+--------------------+| 化工楼 | 1 || 声乐楼 | 2 || 建艺大厦 | 1 || 数学馆 | 2 || 机械大厦 | 1 || 梨园楼 | 2 || 红楼 | 3 || 计算机楼 | 2 || 语言大厦 | 2 || 通信大楼 | 2 |+--------------+--------------------+10 rows in set (0.02 sec)关键词having,用法:在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与合计函数一起使用。
12345SELECT column_name, aggregate_function(column_name)FROM table_nameWHERE column_name operator valueGROUP BY column_nameHAVING aggregate_function(column_name) operator value
实际举个例子:
- ucase()函数,这个函数可以把字段的值变成大写的形式。
- lcase()函数可以吧字段的值变成小写的形式。
- format()函数可以对字段显示进行格式化。
一些基本的逻辑运算,包括union(并),intersect(交),except(差)。
==出现在select子句中但是没有被聚集的字段必须出现在group by子句中。==
用在having中的谓词在形成分组之后才起作用,而where子句中的谓词在分组前起作用。
那什么是谓词呢?