MySQL必知必会

一.数据类型

1.数值型
  • 整数类型,小数类型。默认有符号,可以有负数 -1,无符号可以使用unsigned约束;
  • tinyint 1字节 极小整型;
  • smallint 2字节 小整型
  • mediumint3字节 中整型
  • int/integer 4字节 整型
  • bigint 8字节 大整型
  • float 4字节 单精度小数
  • double 8字节 双精度小数
2.字符型
  • 短文本char和varchar,char不可变成,而char可以变长,长文本text和blob
  • char 固定长度短字符串
  • varchar 不固定长度短字符串
  • text 长字符串,保存文章内容
  • blob 可变长 二进制流,保存图片,媒体信息
3.日期型
  • date 范围为'1000-01-01'到'9999-12-31'
  • Datetime 不存储格式为:YYYY-MM-DD HH:MM:SS
  • TimeStamp 这是时间戳,从1970-01-01 00:00:00到当前的时间差值
  • year MySQL以YYYY格式检索和显示YEAR值。范围是1901到2155。

二.create,Alter,insert,Select,Distinct,Where,NULL,Orderby, Update,Delete等操作

1.create
  • 创建数据库 create database test;
  • 创建表 CREATE TABLE article
    (
    id int,
    title varchar(50),
    content text,
    rank int,
    price decimal(10,2)
    );
2.关于约束
  • DEFAULT 会给字段添加上默认值,若字段在添加的时候没有指定值,则使用默认值。
  • PRIMARY KEY,中文称主键,用于唯一标识数据表中的每一条记录。
  • 主键必须是唯一的,即每条记录的主键必须各不相同;主键不能为空。
  • 每张数据表都应该有一个主键,且每个表只能有一个主键。
  • UNIQUE,用于唯一标识数据表中的每一条记录。
  • UNIQUE 约束的字段必须是唯一的,即该字段在每条记录中必须各不相同。PRIMARY KEY 约束默认拥有 UNIQUE 约束。
  • 每个表可以有多个UNIQUE约束,但是只能有一个PRIMARY KEY。
  • NOT NULL 表示一个字段是非空的,当在插入或者修改时,如果字段为空(NULL)则会报错。
3.alter
  • 新增字段 alter table test add score float;
  • 修改字段 alter table test modify column username username varchar(32);
  • 删除字段 alter table test drop age;
  • 添加索引 alter table test add index age_index(age);
  • 删除索引 alter table test drop index age_index;
  • 修改字段顺序1 alter table test title title varchar(11) after id;
  • 修改字段顺序2 alter table test title title varchar(11) first id;
    总结:Alter 指令给了你吃后悔药的权利,但不要过于依赖它,Alter 指令修改数据表是十分消耗性能和时间的,请不要在线上工作时使用它。
4.drop
  • 删除数据库 drop database test;
  • 删除数据表 drop table test;
  • 清空数据库 truncate table test;
  • 删除视图 drop view test;
5.insert
  • 插入数据 INSERT INTO test VALUES('pedro',23);
  • 批量数据 INSERT INTO test(username,age) VALUES('pedro',23),('mike',18);
6.select
  • 获取数据库版本 select version();
  • 获取当前用户 Iselect current_user;
  • 单字段 select username from test;
    总结:大多数情况下,即使是取表的全字段,也不推荐使用*,显式地给出查询字段,更易维护和合作。
7.Distinct
  • 单字段去重复 select distinct age from test;
  • 多字段去重复 select distinct age,username from test;
    总结:Distinct 是要付出代价的,去掉重复值带来的时间损耗比查询本身更耗时,因此也请慎用。
8.where
  • 运算符 = 等于 <> 不等于 > 大于 < 小于 !<不小于 !>不大于 !=不等于 >=大于等于 <=小于等于
  • 连接符 and 连接两个条件表达式,若二者都为True,返回True,否则返回False
  • or 连接两个条件表达式,若二者都为False,返回False,否则返回True
9.null比较
  • is_null 表示字段为空,is not null 表示字段非空;
  • select username from test where age is null;
  • select username from test wgere age is not null;
10.order by
  • 单字段排序 select username,age from test order by age;
  • 降序 select username from test order by age desc;
  • 升序 select username from test order by age asc;
  • 多字段 SELECT username,age FROM test ORDER BY username, age;
    总结:Order By 可以有效让查询结果有序,这对于数据展示来说至关重要。Order By 对于多字段的排序支持虽然强大,但是很消耗性能。Order By 对于字符串的排序是按位(每个字符)进行比较排序的,十分耗时,一般情况下不推荐使用。
11.update
  • 多字段更新 UPDATE test SET username = '18s' WHERE age=18;
11.delete
  • 删除多行 delete from test where username = 'tanbinghao';

三.SQL高级操作

1.Like和Regexp
  • 单独使用Like SELECT username, age FROM user WHERE username LIKE 'pedro';
  • 搭配单个通配符% SELECT username, age FROM user WHERE username LIKE 'pe%';
  • Like 搭配两个通配符% SELECT username, age FROM user WHERE username LIKE '%e%';
  • Like 搭配通配符_和% SELECT username, age FROM user WHERE username LIKE '_e%';
  • regexp找到p或f的用户 SELECT username,age FROM imooc_user WHERE username REGEXP '[1]';
2.between & In
  • 条件值范围 SELECT username, age FROM user WHERE age BETWEEN 18 AND 24;
  • 年龄不在 18~24 之间的用户 SELECT username, age FROM user WHERE age NOT BETWEEN 18 AND 24;
  • between 和Delete搭配使用 DELETE FROM user WHERE age BETWEEN 18 AND 24;
  • 连续范围内使用 In SELECT username, age FROM user WHERE age IN (18,19,20,21,22,23,24);
  • in可以搭配not SELECT username, age FROM user WHERE age NOT IN (18,23);
3. Union & As
  • 单独使用 Union select username from user_1 union select username from user_2;
  • Union All SELECT username, age FROM user_1 UNION ALL SELECT username, age FROM user_2;
  • as 作为表名称 select * from user1 as user;

总结:union使用场景不多,语法简单,在聚合场景中十分有用,别名使用很频繁,不仅可以提高性能,还可以提高sql的阅读性

4. primary key & Foreign key
  • 主键是数据表每条记录唯一且完整的标识,外键是另一个数据表的字段;

  • 外键是一类特殊的字段,可以像其他普通字段存储数据,更加可以表示表与表之间的关联。
    create table user(
    id serial parimary key,
    username varchar(20),
    age int
    );

    create table user_score(
    id int unsigned parimary key auto_increment,
    user_score int,
    user_id int unsigned,
    foreign key(user_id) fererences user(id)
    );
    postgresql不支持unsigned无符号,无自增约束;

5. 创建时约束
CREATE TABLE user
(
  id int PRIMARY KEY,
  username varchar(20),
  age int CHECK(age > 0)
);

#插入age必须大于0,否则报错

Check 虽然可以约束字段,但是会影响数据插入和更新速度,降低数据库性能,不推荐


4.JOIN查询

1. 连接查询
DROP TABLE IF EXISTS class;
CREATE TABLE class
(
  id int PRIMARY KEY,
  class_name varchar(20)
);
INSERT INTO class(id,class_name) VALUES(1,'SQL必知必会'), (2,'C语言入门'),
(3,'JAVA高效编程'),(4,'JVM花落知多少');

DROP TABLE IF EXISTS user;
CREATE TABLE user
(
  id int PRIMARY KEY,
  username varchar(20),
  class_id int references class(id)
);
INSERT INTO user(id,username,class_id) VALUES(1,'pedro', 1), (2,'peter', 1),
(3,'faker', 2), (4,'lucy', 4),(5,'jery', NULL);
  • 笛卡尔积 SELECT * FROM class CROSS JOIN user;
  • 交叉连接将一张表的每一条记录与另一张表的每条记录排列组合;
2. inner join
  • 将一张表的每一条记录与另一张表的每一行记录进行比较,得到匹配的记录集合;
  • select * from user inner join class on user.class_id = user.class_id;
2. 左外连接,左外连接,全连接;
  • 内连接 select username,class_name from user left join class on user.class_id = class.class_id;
  • 外连接 select username,class_name from user right join class on user.class_id = class.class_id;
  • 全连接 SELECT * FROM user LEFT JOIN class ON class.id = imooc_user.class_id UNION SELECT * FROM user RIGHT JOIN class ON class.id = user.class_id WHERE user.class_id IS NULL;

左外连接若a和b两个表进行做左外连接,会在结果中包含a表的所有记录,没有符合条件的匹配记录null填充

右外连接若a和b两个表进行做右外连接,会在结果中包含b表的所有记录,没有符合条件的匹配记录null填充


四.分组,limit,子查询

1. Select Into
DROP TABLE IF EXISTS imooc_user;
CREATE TABLE user
(
  id int PRIMARY KEY,
  username varchar(20),
  age int,
  birthday date
);
INSERT INTO user(id,username,age,birthday)
VALUES (1,'peter', 18, '2002-10-21'), (2,'pedro', 24, '1996-03-15'), 
(3,'jerry', 28, '1992-02-13'), (4,'mike', 38, '1982-04-01');
  • 备份用户表
2. group & having
  • 单字段 SELECT age, COUNT(*) FROM user GROUP BY age;
  • 多字段 SELECT age, score, COUNT(*) FROM user GROUP BY age, score;
  • 分组后的having过滤 SELECT age, COUNT() FROM user GROUP BY age HAVING COUNT() > 1;
3. limit & offset
  • SELECT username,age FROM user ORDER BY age DESC LIMIT 3;
  • 双参数 SELECT username,age FROM user ORDER BY age DESC LIMIT 0,3;
4. 子查询
  • 子查询的规则:子查询必须在括号内,子查询不能使用order by,主查询可以,子查询不能使用聚合函数中;between不能与子查询一起使用,可使用在子查询内部。子查询返回一条记录,只能使用单值运算符如>,若返回多条,且使用any或all特殊语法;

  • 查询 select username from user where age < (select age from user order by age desc limit 1);

  • insert 搭配子查询
    create table username_copy(username varchar(20));
    insert into username_copy select username from user where age <(SELECT age FROM imooc_user ORDER BY age DESC LIMIT 1);

  • update 搭配子查询 update user set score = score + 100 where id in (select id from user where age > 25 );

  • delete配合 delete from user where id in(select id from user where score > 500);
    子查询诸多限制,而且性能不高,因此如果一次查询解决的问题尽量不要使用子查询


五.事务,索引,视图,锁

事务特点
  • 事务四大特征;ACID
  • 原子性:每个事务都是整体不可再拆分,要么全部成功,要么全部失败;
  • 一致性:事务执行前后数据库的状态必须保持一致,比如A转账B,转账的A和b的总数不变的;
  • 隔离性:事务与事务之间互不影响,彼此隔离;
  • 持久性:事务一旦提交成功,对数据库的更改就是永久;
操作事务
  • 开始事务 begin;
  • insert into user(id,username,age) values(6,'lck',21);
  • 提交事务 commit;
  • 回滚事务 rollback;
并发事务
  • 脏读:A用户开启事务,向user表插入名为tom用户,此时未提交事务,但B用户此时访问了数据库;看到tom用户;A明明还没有提交事务,但是B却看到A的操作结果;
  • 不可重复读:B用户访问了数据库,查看ID为1的用户,比如age等于18,A用户访问数据库,开启了一个事务,修改了id为1的用户age等于100;B又一次查看了id为1的用户此时看到age等于100;
  • 幻读:A开启事务,插入名tom的数据,此时B访问数据库,B查询表看到了tom,而A后悔创建tom用户,于是回滚了事务;
隔离级别
  • 读未提交:会产生脏读,会产生不可重复读,会产生幻读;

  • 读已提交:不会产生脏读,会产生不可重复读,会产生幻读;

  • 可重复读:不会产生产生脏读,不会产生不可重复读,会产生幻读;

  • 可串行化:不会产生脏读,不会产生不可重复读,不会产生幻读;

  • sql server 和 oracle默认隔离级别是:读已提交;Mysql:可重复读;

脏读:读到了其他事务未提交的数据,不可重复读:两次读取到了同一数据的不同结果;幻读:读到了其他事务新增但未提交的数据,而且新增数据并未成功

索引
  • 类型:普通索引,唯一索引,复合索引,主键索引,全文索引;
  • 索引的创建 create index age_index on user(age);
  • 删除 drop index age_index on user;
  • 多字段索引 create index username_age_index on user(username,age);
  • 使用索引:select * from user force index(username_index) where username = 'tanbinghao';
  • 如何创建索引
  • ALTER TABLE table_name ADD INDEX index_name (column); #普通索引
  • ALTER TABLE table_name ADD UNIQUE (column); #唯一索引
  • ALTER TABLE table_name ADD PRIMARY KEY (column); #主键索引
  • ALTER TABLE table_name ADD FULLTEXT (column); #全文索引
  • ALTER TABLE table_name ADD INDEX index_name (column1, column2, column3); #组合索引

索引:减少查询需要扫描的数据量,减少了服务器的排序操作,创建临时表的操作,将服务器的随机IO变成了顺序IO;
索引总结:索引是大数据查询的利器,能显著提升的效率,索引遵循最左原则,即优先匹配左边的元素,联合索引也不例外

索引的优点

  • 减少查询扫描的数据量加快了查询速度

  • 减少服务器的排序操作和创建临时表的操作,加快了group by ,order by 等操作;

  • 将服务器的随机io变为顺序io;

  • 索引的缺点:

  • 索引占用磁盘或者内存空间,减慢了插入更新的操作速度;

  • 创建索引需要注意的点(原则)

  • 1.表的主键,外键必须有索引;

  • 2.数据量超过300的表应该有索引;

  • 3.经常连接的表,在连接字段应该建立索引;

  • 4.经常在where子句的字段,特别是大表的字段,应该建立索引;

  • 索引应该建立小字段,对于大的文本甚至超长字段不要使用索引;

  • 复合索引的建立需要仔细分析,尽量考虑单字段索引代替;

索引为什么失效?

  • 使用不等于查询
  • 列参与了数学运算或者函数
  • 在字符串like时左边是通配符.类似于'%aaa'.
  • 当mysql分析全表扫描比使用索引快的时候不使用索引.
  • 当使用联合索引,前面一个条件为范围查询,后面的即使符合最左前缀原则,也无法使用索引.
视图
  • 创建视图 create view as res select username from user;
  • 使用视图 select * from res;
  • 删除视图 drop view res;
  • 视图可以简化操作,还可以定制数据。视图不易创建太多,由于更新表的同时也会更新关联的视图,降低数据库性能;
  • 颗粒:行锁,表锁,页锁
  • mysql锁分为共享锁和排他锁,也叫做读锁和写锁。
  • 读锁是共享的,可以通过lock in share mode实现,这时候只能读不能写。
  • 写锁是排他的,它会阻塞其他的写锁和读锁。从颗粒度来区分,可以分为表锁和行锁两种。
  • 表锁会锁定整张表并且阻塞其他用户对该表的所有读写操作,比如alter修改表结构的时候会锁表。
  • 行锁又可以分为乐观锁和悲观锁,悲观锁可以通过for update实现,乐观锁则通过版本号实现。
  • 乐观锁:同一数据并发条件下,发生小概率事件,因此我们不加锁,加上判断版本号是否成功;
  • 例如: 两个人都拿到了id=1的订单,修改价格;
  • A执行成功了,B也需要价修改价格;但是并不知道价格已经修改;
  • 很明显B修改了失败,因为修改价格之前A的速度优势已经修改了价格;此时version等于2;
  • 悲观锁:同一数据在并发下,冲突是大概率事件,因此我们必须先加锁,不允许别人修改。
  • 共享锁: lock table test read;
  • 排他锁:lock table test write;
  • 解锁: unlock tables;
  • 全局锁 flush tables with read lock;
  • 整个数据库就会处于只读状态。聪明如你,应该可以猜到全局读锁可能的适用场景了:当我们做数据库备份时,可以使用该锁让全库处于只读状态。
  • 页锁:介于行锁和表锁中间的锁,表锁冲突多,行级锁冲突小,速度慢;BOB支持页级锁;

死锁:产生死锁的原因:系统资源不足,资源分配不当,进程运行推送的顺序不当;

  • 减少死锁的方法:使用事务,不适用lock tables;保证没有长事务,操作完成之后立即提交事务;

MySQL优化

数据库命令规则

  • 所有数据对象名称必须小写,并且下划线分割;
  • 数据库对象命令见名认意,并且不超过32字符;
  • 数据库对象静止使用MySQL保留关键字
  • 临时表必须tmp_前缀并以日期未为后缀;
  • 所有存储相同数据的列名和列类型必须一致;
    设计规范
  • 没有特殊要求默认要求innodb;
  • 不要使用select*,以提高查询速度;
  • 尽量避免向客户端返回大数据量,若数据量过大。应该考虑相应是否合理;
  • 使用表的别名as,可以减少解析时间;
    字段类型优化
  • 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,会降低查询和性能;增加存储的开销;
  • 最好不要给数据库留null,尽量使用not null填充数据库;
    where查询优化
    -进行模糊查询应该注意,除非必要否则不要在关键词前加%,否则导致全表索引查询;
  • 不要在where子句中对字段null值判断,包括not,!=,<>等操作符;
  • 避免在where中出现字段的类型转换,隐式类型转换等等
    索引优化
  • 索引不是越多越好,会降低插入和更新的效率;一个表的索引不要超过6个;
  • 用索引提高效率合理使用,索引和复合索引同样能提高效率;
  • 使用索引字段作为条件,如果该索引是联合索引,那么必须使用索引第一个条件。最左原则;
  • 索引需要空间存储也需要定期维护,每当有记录在表中增减列被修改时,索引本身也会被修改,这意味着每条记录的,插入,删除,更新为此对付出磁盘io,因为所有需要额外的存储空间处理;
    事务优化
  • 尽量使用commit,尽可能使用commit,这样程序性能得到提高;
  • 避免大事务操作,提高系统并发能力;
    临时表
  • 避免频繁创建和删除临时表,以减少系统表资源的消耗;
  • 慎用大的临时表与其他大表的连接查询和修改,减低系统表负担,因为这种操作会在一条语句中多次使用tempdb的系统表。
  • 避免使用distinct,order by,group by ,having,join.这些语句会家中发tempdb的负担;
  • 更多优化,读写分离,主从备份,日志等;

Explain分析
ID
sql存在子查询,那么id序号递增,值越大优先级越高,越先被执行
select_type:主要区分复杂的查询,比如普通查询,联合查询;
select_type

  • simple:表示最简单的查询语句,也就是在查询中不包含子查询获知union交并集等操作;
  • primary: 当查询语句中包含任何复杂的子部分,最外层查询则被标记为primary;
  • subquery:当select或where列表包含子查询,则子查询被标记subquery;
  • derived :表示包含在from子句中的子查询的select,在我们的from列表中包含的子查询会被标记为derived;
  • union :如果union后面又出现了select语句,则会被标记为union;如果union包含在from子句的子查询中,外层select被标记为derived;
  • union result :代表union的临时表中读取数据,而table列的<union,1,4>表示的一个和第四个;

table

  • 查询的表名,并不是真实存在的表,有别名显示;也可能临时表;

partitions

  • 查询匹配到的分区信息,对于非分区值,为null,当查询的是分区表,会显示分区表命中的分区情况;

type

  • system :当表仅有一行记录,数据量很少,往往不需要进行磁盘IO,速度非常快;
  • const :表示查询命中,parimary key,主键或unique唯一索引,或者被连接的部分是一个常量值,这类扫描效率极高,返回数据量少,速度非常快;
  • eq_ref : 命中主键索引,或者唯一索引,type就是eq_ref;
  • ref : 区别于eq_ref ,表示非唯一性索引,会找到多个符合条件;
  • ref_or_null : 这种类型类似于ref,区别在于mysql,会额外搜索包含null值;
  • index_merge : 使用索引合并优化方法,查询使用了两个以上索引;
  • index :读全表,区别在于index遍历索引数读取,而all是从硬盘读取;
  • all:遍历全表找到匹配的行,性能最差;
  • unique_subquery子查询返回不重复的集合,index_subquery 用于非唯一索引,可以返回重复值;
  • range:使用索引选择行,仅检索给定范围的行;

possible_keys

  • 表示在mysql中通过哪些索引,能让我们在表找到想要的记录,一旦查询涉及的某个字段存在索引,则索引被列出;

key

  • 区别于possible_key,key成功查询中实际使用的索引,若没有使用索引;显示为null;

key_len

  • 表示查询使用到索引长度,原则长度越短越好;

ref

  • 常量等值查询,显示const
  • 关联查询,显示关联表的关联字段
  • 查询使用表达式,函数,条件列内部隐式转换为func
  • 其他情况 null

rows

  • 表的统计和索引使用情况,mysql扫描的行数,直观的显示sql的性能好坏;rows值越小越好

filtered

  • 百分比的值,表示符合条件的记录数的百分比;

Extra

  • using index : select操作使用了覆盖索引,通俗就是查询的列被索引覆盖,使用覆盖索引查询速度非常快;
  • Using where 查询未找到可用的索引,进而通过where条件过滤所需数据,但是并不是带where语句的查询都会显示;
  • Using temporary : 查询结果使用临时表来存储,一般在排序或者分组查询用到;
  • Using filesort 无法利用索引完成排序,也就是order by 字段没有索引,通过需要sql优化;
  • Using join buffer : 联表查询,表的连接条件没有用到索引,需要有一个连接缓冲区来存储中间结果;
  • Impossible where : 不太正确where语句,导致没有符合条件的行;
  • No tables used : 查询语句没有from子句,或者有from dual子句;

重要的几项:

  • possible_keys:利用索引的名字,这里的索引是创建索引时指定的索引昵称;
  • key:显示mysql实际使用的索引名字,它为空,则mysql不使用索引
  • key_len:列出常量const
  • rows:扫描的记录数,理想值数字是1

慢日志查询

关于日志和数据文件
  • 日志文件:二进制日志,innoDB redo log,错误日志,慢查询,查询日志;
  • 数据文件:innodb(.idb,ibdata),Myisam(.myd,myi)
  • 二进制日志:以二进制形式,记录query语句,执行时间,相关事务信息;
    ###### binlog 的开启,通过在配置文件 my.cnf log-bin = /mysql/log/mysql-bin # binlog的存储路径 `

重要日志模块:InnoDB redo log,是存储引擎 InnoDB 生成的日志,主要为了保证数据的可靠性
innodb_log_file_size = 1000M # 每个redo log文件的大小
innodb_log_files_in_group = 3 # redo log文件数量

慢查询日志:slow query log,记录 MySQL 中执行时间较长的 query,包括执行时间、执行时长、执行用户、主机等信息。
slow_query_log = 1 #开启慢查询
long_query_time = 1 #设置慢查询阈值为1s
`slow_query_log_file = /mysql/log/mysql-slow.log #设

  • 手动添加
  • show global variables like 'slow_query_log%' 是否开启
  • set global slow_query_log = on;
  • set global slow_query_log_file = "/var/lib/mysql/slow_log.log";
    置慢查询日志存储路径一般查询日志:general query log,慢查询记录的是超过阈值的 query,而一般查询日志记录的是所有的 query。一般查询日志的开启需要慎重,因为开启后对 MySQL 的性能有比较大的影响。general_log = OFF #默认是关闭的 general_log_file = /mysql/data/mysql-general.log #设置查询日志存储路径数据文件.frm 文件存放表相关的元数据,包括表结构信息等。 每张表都有一个对应的 .frm 文件,不管这张表使用哪种存储引擎。`
Show Profile 分析查询
  • 开启set profiling=1;
问题

InnoDB 引擎
.ibd 文件和 ibdata 文件都是 InnoDB 引擎的数据文件

  • 如果是独享表空间的存储方式,则使用.idb文件来存放数据,每张表都会有一个单独的 .ibd 文件。
  • 如果是共享表空间的存储方式,则使用ibdata文件来存放数据,所有表共用一个 ibdata 文件。
    MyISAM 引擎的数据文件包含 .MYD 文件和 .MYI 文件。
    MYD 文件,存放 MyISAM 的数据,每张表都有一个单独的 .MYD 文件。
    .MYI 文件,存放 MyISAM 的索引相关信息,每张表都有一个单独的 .MYI 文件,与 .MYD 文件的存储路径一致。
  • innodb支持事务,而myisam不支持事务,崩溃后无法安全恢复,表锁非常影响性能;
  • innodb 支持行级锁,而myisam支持表级锁;
  • innodb 支持外键,而myisam不支持;
  • InnoDB不支持全文索引,而MyISAM支持,可以支持复杂的查询(5.6版本之后支持全文索引)
  • InnoDb实现了四个标准的隔离级别 而MyISAM不支持
  • memory不支持事务,不支持外键,所有数据都在内容中,数据速度快,但是安全性不高,大小要要求,不能建立太大的表。
三范式规则
  • 第一范式:每个列都不可以再拆分;
  • 第二范式:非主键列完全依赖主键,而不能依赖主键的一部分;
  • 第三范式:非主键列只依赖于主键,不依赖于其他非主键
索引是什么样的数据结构
  • 索引的数据结构和具体存储引擎的实现有关, 在MySQL中使用较多的索引有Hash索引,B+树索引等,而我们经常使用的InnoDB存储引擎的默认索引实现为:B+树索引.
函数
  • 新建函数
    create function getUserName(uid int ) returns varchar(20)
    begin
    declare uname varchar(20),
    select username from user where id = uid into uname;
    return uname;
    end;

  • 执行函数 SELECT getUserName(1);

  • if判断 : SELECT name,IF(age > 17,'成年','未成年') AS age_group,id_number FROM student;

  • case条件
    SELECT
    *,
    CASE name
    WHEN 'Tom' THEN '汤姆'
    WHEN 'Jack' THEN '杰克'
    WHEN 'Mary' THEN '玛丽'
    WHEN 'Timo' THEN '提莫'
    WHEN 'Bob' THEN '鲍勃'
    WHEN 'Judy' THEN '朱蒂'
    ELSE '未定义' END AS 'chinese_name'
    FROM teacher;

  • abs 取绝对值

  • mod 取余数

  • round 四舍五入

  • count 得到总行数

  • max 得到最大值

  • min 得到当前时间戳

  • sum 将英文字符串全部转为小写

  • avg 得到平均值

  • current_date 得到当前日期

  • current_timestamp 得到当前时间戳


  1. pf ↩︎

posted @ 2021-02-22 14:22  惊风破浪的博客  阅读(125)  评论(0编辑  收藏  举报