存储引擎是表级属性,在创建表时指定;
MyISAM ,不支持事务,外键,没有行锁,优点是访问速度快,适合于多 select,insert into 操作的弱事务性的应用中,单个MyISAM表实际上由.frm(表定义文件),.MYD(表数据文件),.MYI(表索引文件)三个文件构成;
InnoDB,支持行锁,事务和外键,是建表的默认引擎,
MEMORY,表数据是存储在内存中,性能最好,但 Mysql 实例重启,数据会丢失;
MERGE,是一组 MyISAM 表的组合,查询,删除,更新都是对内部的 MyISAM表 的操作,插入操作需要指定表,通常用来突破对单个MyISAM的限制;
MyISAM 和 InnoDB 默认使用 b-tree 的索引结构,而 MEMORY 默认使用 hash 结构的索引,hash 结构的索引,等值查找非常快,但范围查找,需要走全表扫描,b-tree 索引,等值查找,时间复杂度是 O(log2N),范围查找也可以用到索引;
// 例如,查询数据库 test1 下所有前缀为 tmp 的表:
select table_name from tables where table_schema='test1' and table_name like 'tmp%';
// 选择数据库使用
use db1
// 显示当前数据库所有的表,显示所有数据库
show tables
show databases
// 显示 tb1 的表结构
desc tb1
// 显示建表的 sql 语句
show create table tb1
整数类型:TINYINT,SMALLINT,MEDIUMINT,INT(4字节),BIGINT(8字节)等,
可指定字段宽度,INT(10),表示1最小长度是 10,可设置 zerofill,表示不足用0填充
浮点数类型:FLOAT,DOUBLE,取值都是 4 舍 5 入;
定点数:DEC,默认精度和标度是 DEC(10,0)
定点数都可以用(M,D)表示,M 表示数字位数,D 表示小数点后的位数,超过是直接截取
精度要求高的场景,建议使用定点数
CHAR(M),VARCHAR(M):表示定长和非定长的字符串,M 定义了最大长度,存储时,CHAR 是固定 M 长度,VCHAR 不固定
检索的时候其中CHAR(M)会去除右边多余的空格,而VARCHAR(M)会保留右边的空格;
建议 MyISAM 引擎,使用 char,而 InnoDB引擎,使用 varchar,
对于 memory 引擎,char 和 varchar 都会按照 char 处理
create table t1(vc varchar(4), c char(4));
insert into t1 values('ab ','ab ');
select length(vc),length(c) from t1;
4 2
时间字段:DATE,DATETIME(只跟插入时的时区相关),TIME,TIMESTAMP(插入和查询时都受时区影响),YEAR
create table tb1( time1 datetime ,time2 timestamp );
insert into tb1(time1,time2) values(now(),now());
set time_zone = '+9:00';
selct * from tb1;
2007-09-25 18:26:50(查询时东九区的时间)和 2007-09-25 17:26:50(插入时东八区的时间)
并且数值,字符串均可插入到时间字段
insert into table1(date) values(20170725115520) 或者 values('20170725115620')
或者 value('2017-07-25 11:56:20');
二进制字节存储:BINARY(M),VARBINARY(M)
枚举类型:ENUM,SET
大容量字段: TEXT,BLOB,其中 text 只能存储字符数据
字符串函数:
TRIM(str):去除空格,SUBSTRING(str,x,y):从x 位置起截取 y 长度
LEFT(str,len),RIGHT(str,len):从左,从右,截取 len 长度
STRCMP(s1,s2):比较字符串的 ASCII 大小
数值函数:
CEIL(x):向上取整
TRUNCATE(x,y):截断 x 为 y 位小数
ROUND(x,y):将 x 四舍五入,保留 y 位小数
日期函数:
CURDATE():当前日期
CURTIME():当前时间
NOW():当前日期和时间
DATE_FORMAT(date,fmt):按 fmt 格式化日期 date
如:select date_format(now(),'%Y%m%d %T')
20170904 14:52:00
DATE_ADD(date,INTERVAL expr type):返回date加上一个时间间隔的日期;
DATEDIFF(expr,expr2):返回expr2到expr间隔天数;
流程函数:
IF(value,t,f)
IFNULL(val1,val2):如果 val1 不为 null 返回val1,如果 val1 为 null 返回 val2;
CASE WHEN ... THEN ... ELSE ... END;
CASE expr WHEN val THEN ... ELSE ... END;
MD5(str);
INET_ATON(ip),INET_NTOA(num):ip和数字之间的转换,方便ip的比较;
USER(),VERSION(),DATABASE();
alter table tname modify cname ctype
alter table tname drop cname ctype
alter table tname change cname1 cname2 ctype
// 删除表中数据,保留表结构,并且新增是从删除的递增id开始
truncate table tname
// table2_cname为主表
mysql的这种外键不会生效,mysql需要用表级约束来创建外键
create table tname{
cname1 ctype,
cname2 ctype,
foreign key(cname2) references tname2(table2_cname)
}
// 如果想定义删除主表记录时也将从表外键关联的记录也删除或置空,可以使用
foreign key(cname2) references tname2(table2_cname) on delete set null
foreign key(cname2) references tname2(table2_cname) on delete cascade
like 条件,% 匹配任意字符任意次数,_ 匹配任意字段单次,convert 函数,用于数据类型转换,count 函数,如果是字段会忽略 null 的记录,如果是 count(星) 就包含 null 的记录;特殊的函数,ifnull(exp1,exp2),case condition when …end;
group by,where 和 having 子句同时出现,首先执行 where 筛选,得到的结果集按 group by 进行分组,最后使用 having 进行分组后的过滤;
子查询
// >any 表示大于其中任何一个值即可,>all 表示需要大于所有值
select * from table1 where table1_cname > any(select table2_cname from table2)
连接 join 操作,left join 表示,无论左表是否有匹配,全量输出,right join 相反,inner join 表示,只输出匹配的记录,而 outer join 表示,左右表,无论是否匹配,都会全量输出;
触发器,是指定义在 insert,update,delete 操作前后,执行的一些操作;information_schema 库的表 triggers 保存了该库的所有触发器信息;
关键字 Like,% 匹配任意零或多个字符,不会匹配 null,_ 匹配单个字符,默认是不区分大小写,注意,Like “1000” 是不会查出值为1000的行;
关键字 Regexp,正则匹配,默认不区分大小写,添加 binary,让其区分大小写,+ 代表1次或多次匹配,* 代表0次或多次匹配,?代表0次或1次匹配;
information_schema 库的表 views 保存了该库的所有视图信息
存储过程,是指一段 sql 语句的集合,将逻辑判断,计算过程转移到数据库服务器,但要注意不能给数据库服务造成过大压力,information_schema 库的表 routines 保存了该库的所有存储过程信息;
事件调度器,每隔一段时间执行的逻辑
// 每 5 s 插入 test 表一条数据
create event test_event on schedule every 5 second do insert into test.test(id,create_time) values('test',now());
创建用户,命令 create user ‘userName’@‘ip’ identified by ‘password’,Mysql 使用 用户名 + ip 来表示一个用户, mysql.user 表记录了用户信息,内存中数组 acl_users 记录了全局权限; mysql.db 表记录基于库的权限,在内存里,保存在数组 acl_dbs 中,更细的还有表的权限和列的权限 mysql.tables_priv,mysql.columns_priv;
grant 命令用于给用户赋权,revoke 命令用户收回权限;flush privileges 语句,是用数据表的数据重建一份内存权限数据,通常在直接使用了 DML 操作了数据表,导致不一致才使用;
grant all privileges on *.* to 'ua'@'%' with grant option;
revoke all privileges on *.* from 'ua'@'%';
下载社区版,zip 免安装,解压即可,环境变量 PATH 增加 /bin,执行 mysqladmin --version 查看,下载地址:https://dev.mysql.com/downloads/mysql/;
新建 data 文件夹,cmd 中执行 mysqld --initialize (–secure --user=mysql)来初始化 data 目录,不生成随机密码,进入数据库后,通过 set Password(‘dengh’) 来设置;
zip 解压目录,新建 my.ini 配置文件,安装 mysql 服务,在安装目录 /bin,管理员运行 cmd,执行 mysqld install( mysqld remove 移除服务),执行 net start mysql 启动mysql 服务( net stop mysql 停止 mysql 服务),通过 data/hostname.err 查看启动日志;
连接数据库,mysql -u root -p(mysql -h127.0.0.1 -P3306 -uroot -p来连接远程数据库),更多参考:https://blog.csdn.net/mhmyqn/article/details/17043921
my.ini 配置文件:
[client]
port=3306
default-character-set=utf8
[mysqld]
port=3306
character_set_server=utf8
#解压目录
basedir=E:\devTools\mysql-5.7.15-winx64\mysql-5.7.15-winx64\
#解压目录下data目录
datadir=E:\devTools\mysql-5.7.15-winx64\mysql-5.7.15-winx64\data
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
skip-grant-tables
[WinMySQLAdmin]
E:\devTools\mysql-5.7.15-winx64\mysql-5.7.15-winx64\bin\mysqld.exe
set password for user@ip = password('新密码');
set password for root@localhost = password('123');
mysqladmin -u用户名 -p旧密码 password 新密码
mysqladmin -uroot -p123456 password 123
use mysql;
update user set password=password('123') where user='root' and host='localhost';
flush privileges;
1. 关闭正在运行的 MySQL 服务,在 mysql\bin 目录 cmd 执行 mysqld --skip-grant-tables,意思是启动 MySQL 跳过权限认证;
2. 重新到 mysql\bin 目录cmd ,执行 mysql,连接权限数据库 use mysql,修改 user 表密码
3. update user set password=password("123") where user="root";
4. 并刷新权限:flush privileges; 退出 quit
5. 最后就可以使用 root 和设置的新密码登录
myISAM 对表总数有缓存,innodb 没有该缓存;
sql 中字符串,使用单引号;
Mysql 中 null 值和任何值都不相等,所以 unique 约束字段,可以有多个 null;
主键,外键和唯一约束,都会自动添加索引;