sql基础
1.关系型数据库与非关系型数据库
2.sql类别
- DDL(Data Definition Language,数据定义语言) (create,drop,alter)
- DQL(Data Query Langauge,数据查询语言)(select)
- DML(Data Manipulation Langauge,数据操纵/管理语言) (insert,delete,update)
- DCL(Data Control Language,数据控制语言) grant(授权),revoke(撤销权限)
- TCL(Transaction Control Language,事务控制语言) commit(提交事务),rollback(回滚事务)
3.数据库三范式
- 第一范式:每个列都不可以再拆分。
- 第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分。
- 第三范式:在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非主键。
4.数据类型
- 整数类型:tinyint、int
- 小数类型:double、float、decimal
- 日期类型:date、timestamp
- 文本:char、varchar、BLOB、text
任何整数类型都可以加上UNSIGNED属性,表示数据是无符号的,即非负整数。
tinyint 型的字段不设置UNSIGNED类型,存储-128到127的整数,否则0到255的整数。
1个tinyint型数据只占用一个字节;一个int型数据占用四个字节。tinyint(2),2指的是存储宽度,不表示存储长度。如果列指定了zerofill 就会用0填充显示,例如tinyint(2)指定后2就会显示为02,自动左边补零。
DECIMAL可以用于存储比BIGINT还大的整型,能存储 精确的小数。计算时FLOAT和DOUBLE相比DECIMAL效率更高一些,DECIMAL你可以理解成是用字符串进行处理。
VARCHAR使用额外1或2个字节存储字符串长度。列长度小于255字节时,使用1字节表示,否则使用2字 节表示。 VARCHAR存储的内容超出设置的长度时,内容会被截断。
CHAR是定长的,根据定义的字符串长度分配足够的空间。CHAR会根据需要使用空格进行填充方便比较。 CHAR适合存储很短的字符串,或者所有值都接近同一个长度。 CHAR存储的内容超出设置的长度时,内容同样会被截断
使用策略
- 存储经常变更的数据,CHAR比VARCHAR更好,因为CHAR不容易产生碎片。 对于非常短的列,CHAR比VARCHAR在存储空间上更有效率。 使用时要注意只分配需要的空间,更长的列排序时会消耗更多内存。
- 尽量避免使用TEXT/BLOB类型,查询时会使用临时表,导致严重的性能开销。
- 尽量使用timestamp,空间效率高于datetime,用整数保存时间戳通常不方便处理。 如果需要存储微妙,可以使用bigint存储。
5.超键、候选键、主键、外键
- 超键:在关系中能唯一标识元组的属性集称为关系模式的超键。一个属性可以为作为一个超键,多个属性组合在一起也可以作为一个超键。超键包含候选键和主键。
- 候选键:是小超键,即没有冗余元素的超键。
- 主键:数据库表中对储存数据对象予以唯一和完整标识的数据列或属性的组合。一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null)。
- 外键:在一个表中存在的另一个表的主键称此表的外键。
6.SQL约束
- NOT NULL: 用于控制字段的内容一定不能为空(NULL)。
- UNIQUE: 控件字段内容不能重复,一个表允许有多个 Unique 约束。
- PRIMARY KEY: 也是用于控件字段内容不能重复,但它在一个表只允许出现一个。
- FOREIGN KEY: 用于预防破坏表之间连接的动作,也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。
- CHECK: 用于控制字段的值范围。
7.关联查询
- 交叉连接(CROSS JOIN)
- 内连接(INNER JOIN)
- 外连接(LEFT JOIN/RIGHT JOIN)
- 联合查询(UNION与UNION ALL)
- 全连接(FULL JOIN)
交叉连接(CROSS JOIN)
-- 交叉连接 没有任何关联条件,结果是笛卡尔积,结果集会很大,
SELECT * FROM A,B(,C);-- 或者
SELECT * FROM A CROSS JOIN B (CROSS JOIN C);
内连接(INNER JOIN)
内连接分为三类
等值连接:ON A.id=B.id
不等值连接:ON A.id > B.id
自连接:SELECT * FROM A T1 INNER JOIN A T2 ON T1.id=T2.pid
外连接(LEFT JOIN/RIGHT JOIN)
左外连接:LEFT OUTER JOIN, 以左表为主,先查询出左表,按照ON后的关联条件匹配右表,没有匹配到的用NULL填充,可以简写成LEFT JOIN
右外连接:RIGHT OUTER JOIN, 以右表为主,先查询出右表,按照ON后的关联条件匹配左表,没有匹配到的用NULL填充,可以简写成RIGHT JOIN
联合查询(UNION与UNION ALL)
SELECT * FROM A UNION SELECT * FROM B UNION ...1就是把多个结果集集中在一起,UNION前的结果为基准,需要注意的是联合查询的列数要相等,相同的记录行会合并如果使用UNION ALL,不会合并重复的记录行效率 UNION 高于UNION ALL
全连接(FULL JOIN)
全连接(FULL JOIN)MySQL不支持全连接可以使用LEFT JOIN 和UNION和RIGHT JOIN联合使用
子查询的三种情况
1.子查询是单行单列的情况:结果集是一个值,父查询使用:=、 等运算符
-- 查询工资最高的员工是谁?
select * from employee where salary=(select max(salary) from employee);
2. 子查询是多行单列的情况:结果集类似于一个数组,父查询使用:in 运算符
3. 子查询是多行多列的情况:结果集类似于一张虚拟表,不能用于where 条件,用于select子句中做为子表
8.其他
8.1 mysql中in和exists区别
mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询。一直大家都认为exists比in语句的效率要高,这种说法其实是不准确的。这个是要区分环境的。
1. 如果查询的两个表大小相当,那么用in和exists差别不大。
2. 如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in。
3. not in 和not exists:如果查询语句使用了not in,那么内外表都进行全表扫描,没有用到索引;而not extsts的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快
8.2 varchar与char的区别
char的特点:char表示定长字符串,长度是固定的;如果插入数据的长度小于char的固定长度时,则用空格填充;因为长度固定,所以存取速度要比varchar快很多,甚至能快50%,但正因为其长度固定,所以会占据多余的空间,是空间换时间的做法; 对于char来说, 最多能存放的字符个数为255,和编码无关。
varchar的特点:varchar表示可变长字符串,长度是可变的;插入的数据是多长,就按照多长来存储;varchar在存取方面与char相反,它存取慢,因为长度不固定,但正因如此,不占据多余的空间,是时间换空间的做法;对于varchar来说, 多能存放的字符个数为65532 ,
结合性能角度(char更快)和节省磁盘空间角度(varchar更小),具体情况还需具体来设计数据库才是妥当的做法