Made By Herolh
服务端
客户端
Mysql是最流行的关系型数据库管理系统,在 WEB 应用方面MySQL是最好的RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一。
由瑞典MySQL AB公司开发,目前属于Oracle公司。
数据库(Database)是按照数据结构来组织、存储和管理数据的仓库
我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢。
所以,现在我们使用关系型数据库管理系统(RDBMS)来存储和管理的大数据量。所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。
每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据。
RDBMS即关系数据库管理系统(Relational Database Management System)的特点:
-- 关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
mysql -u root [-h 主机] -p
# 查看mysql的进程(LINUX下)
ps -ef |grep mysql
status: 查看默认设置
desc 表名; 查看表结构
create user ‘username’@‘pasword‘ *identified by* ‘password‘
use mysql;
grant create,delete,drop,update,insert,select # 或者直接写grant all
on TUTORIALS.* # 所有数据库.所有表
to ‘username‘@‘localhost‘
# 用户名@ 从哪台机子登陆 ‘%‘ 代表任意主机登陆
IDENTIFIED by ‘password‘ # 登陆密码
;
grant all privileges *on 库名.表名 to* ‘username‘@‘%‘
revoke al privileges on 库名.表名 *from* ‘username‘@‘%‘
show grants for 用户名;
charset = GBK;
create 库名 default charset = utf8;
查看查看MySQL数据库服务器和数据库MySQL字符集。
show variables like ‘%char%‘;
# 输出结果
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 (客户端字符集) |
| character_set_connection | utf8 |
| character_set_database | latin1 (数据库字符集) |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 (服务器字符集) |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
查看MySQL数据表(table)的MySQL字符集。
show table status from sqlstudy_db like ‘%countries%‘;
# 输出结果
+---------+--------+--------+------------+------+-----------------+
| Name | Engine | Version| Row_format | Rows | Collation |
+---------+--------+--------+------------+------+-----------------+
|countries| InnoDB | 10 | Compact | 11 | utf8_general_ci |
+---------+--------+--------+------------+------+-----------------+
查看MySQL数据列(column)的MySQL字符集。
show full columns from countries;
+----------------------+-------------+-----------------+
| Field | Type | Collation |
+----------------------+-------------+-----------------+
| countries_id | int(11) | NULL |
| countries_name | varchar(64) | utf8_general_ci |
| countries_iso_code_2 | char(2) | utf8_general_ci |
| countries_iso_code_3 | char(3) | utf8_general_ci |
| address_format_id | int(11) | NULL |
+----------------------+-------------+-----------------+
/*建立连接使用的编码*/
set character_set_connection=utf8;
/*数据库的编码*/
set character_set_database=utf8;
/*结果集的编码*/
set character_set_results=utf8;
/*数据库服务器的编码*/
set character_set_server=utf8;
alter database 库名 default character set 字符集;
alter table 表名 convert to character set 字符集;
alter table 表名 modify 字段名 字段属性 character set gbk;
修改 mysql 配置文件
sudo vi /etc/my.cnf
在 [mysqld]
上方添加以下设置:
default-character-set=utf8
在[mysqld]下方添加以下设置:
character-set-server=utf8
collation-server=utf8_general_ci
engine = inodb
show databases;
create database 库名; # 这么写默认不能处理中文
create database 库名 charset utf8; # 解决中文字符处理问题:
drop database 库名;
use 数据库名;
show tables;
desc 表名;
-- 或
show colums from 表名;
CREATE TABLE table_name (column_name column_type);
INSERT INTO table_name ( field1, field2,...fieldN )
VALUES ( value1, value2,...valueN );
SELECT column_name,column_name
FROM table_name
[WHERE Clause]
[OFFSET M ][LIMIT N]
UPDATE table_name SET field1=new-value1, field2=new-value2
[WHERE Clause]
DELETE FROM table_name [WHERE Clause]
int
decimal
datatime
char,text
性别 enum( ‘‘,‘’ ) username char
set()
数据类型: | 描述 | 存储 |
---|---|---|
char(n) | 固定长度的字符串。最多 8,000 个字符。 定义类型为char(5),那么就表示该类型可以存储5个字符 即使存入2个字符,剩余的3个字符也会用空格补齐。 |
Defined width |
varchar(n) | 可变长度的字符串。最多 8,000 个字符。 定义类型为varchar(5),那么就表示该类型可以存储5个字符 如果存入 2 个字符,字符长度就是 2 而不是 5 |
2 bytes + number of chars |
varchar(max) | 可变长度的字符串。最多 $1,073,741,824$ 个字符。 | 2 bytes + number of chars |
text | 可变长度的字符串。最多 2GB 文本数据。 | 4 bytes + number of chars |
nchar | 固定长度的 Unicode 字符串。最多 4,000 个字符。 | Defined width x 2 |
nvarchar | 可变长度的 Unicode 字符串。最多 4,000 个字符。 | |
nvarchar(max) | 可变长度的 Unicode 字符串。最多 536,870,912 个字符。 | |
ntext | 可变长度的 Unicode 字符串。最多 2GB 文本数据。 | |
bit | 允许 0、1 或 NULL 如果表中的列为8bit,则这些列作为一个字节存储 如果列为9-16bit,这这些列作为2个字节存储,以此类推 |
|
binary(n) | 固定长度的二进制字符串。最多 8,000 字节。 | |
varbinary | 可变长度的二进制字符串。最多 8,000 字节。 | |
varbinary(max) | 可变长度的二进制字符串。最多 2GB。 | |
image | 可变长度的二进制字符串。最多 2GB。 |
数据类型 | 描述 | 存储 |
---|---|---|
tinyint | 允许从 $0$ 到 $255$ 的所有数字。 | 1 字节 |
smallint | 允许介于 $-32,768$ 与 $32,767$ 的所有数字。 | 2 字节 |
int | 允许介于 $-2,147,483,648$ 与 $2,147,483,647$ 的所有数字。 | 4 字节 |
bigint | 允许介于 $-9,223,372,036,854,775,808$ ~ $9,223,372,036,854,775,807?$ 之间的所有数字。 | 8 字节 |
decimal(p,s) | 固定精度和比例的数字。 允许从 $-10^{38} +1$ 到 $10^{38} -1?$ 之间的数字。 p 参数指示可以存储的最大位数(小数点左侧和右侧)。 p 必须是 1 到 38 之间的值。默认是 18。 s 参数指示小数点右侧存储的最大位数。s 必须是 0 到 p 之间的值。默认是 0。 |
5-17 字节 |
numeric(p,s) | 固定精度和比例的数字。 允许从 $-10^{38} +1$ 到 $10^{38} -1$ 之间的数字。 p 参数指示可以存储的最大位数(小数点左侧和右侧)。 p 必须是 1 到 38 之间的值。默认是 18。 s 参数指示小数点右侧存储的最大位数。s 必须是 0 到 p 之间的值。默认是 0。 |
5-17 字节 |
smallmoney | 介于 $-214,748.3648$ 与 $214,748.3647$ 之间的货币数据。 | 4 字节 |
money | 介于 $-922,337,203,685,477.5808$ ~ $922,337,203,685,477.5807?$ 之间的货币数据。 | 8 字节 |
float(n) | 从 $-1.79E + 308$ 到 $1.79E + 308$ 的浮动精度数字数据。 n 参数指示该字段保存 4 字节还是 8 字节。float(24) 保存 4 字节,而 float(53) 保存 8 字节。n 的默认值是 53。 |
4 或 8 字节 |
real | 从 $-3.40E + 38$ 到 $3.40E + 38$ 的浮动精度数字数据。 | 4 或 8 字节 |
数据类型 | 描述 | 存储 |
---|---|---|
datetime | 从 1753 年 1 月 1 日 到 9999 年 12 月 31 日,精度为 3.33 毫秒。 | 8 字节 |
datetime2 | 从 1753 年 1 月 1 日 到 9999 年 12 月 31 日,精度为 100 纳秒。 | 6-8 字节 |
smalldatetime | 从 1900 年 1 月 1 日 到 2079 年 6 月 6 日,精度为 1 分钟。 | 4 字节 |
date | 仅存储日期。从 0001 年 1 月 1 日 到 9999 年 12 月 31 日。 | 3 bytes |
time | 仅存储时间。精度为 100 纳秒。 | 3-5 字节 |
datetimeoffset | 与 datetime2 相同,外加时区偏移。 | 8-10 字节 |
timestamp | 存储唯一的数字,每当创建或修改某行时,该数字会更新。 timestamp 值基于内部时钟,不对应真实时间。 每个表只能有一个 timestamp 变量。 |
数据类型 | 描述 |
---|---|
sql_variant | 存储最多 8,000 字节不同数据类型的数据,除了 text、ntext 以及 timestamp。 |
uniqueidentifier | 存储全局唯一标识符 (GUID)。 |
xml | 存储 XML 格式化数据。最多 2GB。 |
cursor | 存储对用于数据库操作的指针的引用。 |
table | 存储结果集,供稍后处理。 |
*auto_increment
%
_
多表连接
左右联表 : join
上下联表 : union
自动去重:
select * from 表1 (假设十条)
union
select * from 表2 (假设十条)
(返回二十条)
不去重
select * from 表1 (假设十条)
union
select * from 表1
(返回二十条)
select * from 表名 limit 0,10;
( 翻的页越大越慢 )---> 加速方法:只对索引进行扫描
# 覆盖索引,但是快不了多少
select * from userinfo3 where uid in ( select uid from limit 20000,10)
记录当前页最大值最小值ID:
# 当前页后十条
select * from userinfo3 where uid > 20000 limit 10;
# 当前页前十条
select * from userinfo3 where uid < 20000 order by id desc limit 10;
# 上一页:
select * from userinfo3 where uid > max_id limit 10;
# 下一页:
select * from userinfo3 where uid < min_id order by id desc limit 10;
# 上一页:
select * from userinfo3 where id in (
select id from (select id from userinfo3 where id > max_id limit 30) as N order by N.id desc limit 10
)
create views 视图名称 as SQL语句( select ....) # 从真实表动态获取数据
使用视图时,将其当作表进行操作即可,由于视图是虚拟表,所以无法使用其对真实表进行创建、更新和删除操作,仅能做查询用。
alter views 视图名称 as SQL语句( select ....)
删除视图:
drop views 视图名称
当对某张表做增删改操作时,可以使用触发器自定义关联行为
create trigger 触发器名称 before/after (SQL行为语句) ON 表、库
eg:
create trigger tri_before_insert before insert ON tb1 [For EACH ROW 每插入一行就会触发 ]
begin
...;
end
create trigger tri_before_insert after insert ON tb1 For EACH ROW
begin
...;
end
# 查询不会触发触发器
select 函数名();
select CURDATE(); # 2018-05-15 年-月-日
select CURRENT_TIMESTAMP(); # 2018-05-15 20:53:36 年-月-日 时:分:秒
select CHAR_LENGTH(str); # 字符串str长度
select CONCAT(str1,str2) # 字符串拼接
delimiter //
create function f1(
i1 int, --传入参数
i2 int
)
return int
begin
-- 不能写 select * from 表名 等SQL行为
declare num int default 0; # 定义临时变量
set num = i1 + i2;
return(num);
END//
delimiter ;
mysql 前几年还没有这个
保存在 MySQL 上的一个别名 => 一坨SQL语句
delimiter //
create procedure p1()
begin
INSERT INTO userinfo(username,password) VALUES("user5","pd5");
SELECT * FROM userinfo;
end//
delimiter ;
delimiter //
create procedure p2(
in n1 int,
in n2 int
)
begin
select * from userinfo where id > n1;
end//
delimiter ;
存储过程没有返回值的概念,out 是传进一个变量,然后你可以在存储过程中改变该变量的值
out 不往里面传值,也就是虽然在外面 @var=1
,实际上 p3 里使用不了 @var
的值
delimiter //
create procedure p3(
in n1 int,
out n2 int
)
begin
set n2 = 123123;
select * from userinfo where id > n1;
end//
delimiter ;
set @var = 1; # 定义一个变量@var = 0
call p3(8,@var );
select @var # @var = 123123
inout:即可往存储过程里面传值,也可以往外传值
为什么要有结果集,又要有out伪造的的返回值?
out用于设置一个值,标识存储过程的执行结果
call p1();
网络传的数据就少了
存储过程如果改了,程序就GG了
MySQL: 存储过程
程序:调用存储过程
MySQL:。。
程序:SQL语句
MySQL:。。
程序:类和对象(SQL语句)
delimiter //
create procedure p4(
out status int
)
BEGIN
# 声明如果出现异常则执行
{
set status = 1;
rollback;
}
#开始事务
SQL;
commit;
# 结束
set status = 2;
END //
delimiter ;
语法代码
delimiter \create PROCEDURE p5(
OUT p_return_code tinyint
)
BEGIN
DECLARE exit handler for sqlexception --声明如果出现异常则执行
BEGIN
-- ERROR
set p_return_code = 1;
rollback;
END;
START TRANSACTION; --开始事务
DELETE from tb1;
insert into tb2(name)values(‘seven‘);
COMMIT;
-- SUCCESS
set p_return_code = 2;
END\delimiter ;
declare my_cursor CURSOR FOR [SQL语句]select * from A;
fetch my_cursor into row_namename,row_psd;
delimiter \create procedure p6()
BEGIN
DECLARE row_name varchar(20); -- 自定义一个变量1
DECLARE row_psd varchar(50); -- 自定义一个变量2
declare done int default False; -- 自定义循环结束标志
declare my_cursor CURSOR FOR select username,password from userinfo;
declare CONTINUE HANDLER FOR NOT FOUND set done = TRUE;
-- 当游标为空时改变循环结束标志
open my_cursor; -- 打开游标
SIGN:LOOP -- 开始循环标志
fetch my_cursor into row_namename,row_psd; -- 获取游标内容
if done then
leave SIGN; -- breake
end if;
insert into userinfo2( row_namename,row_psd) values( row_name,row_psd);
end loop SIGN; -- 关闭循环标志
close my_cursor; -- 关闭游标
END\delimiter ;
delimiter \create procedure p7(
in str varchar(255), # 放要执行的SQL语句
in arg int
)
begin
1. 预检测某个东西 SQL语句合法性
2. SQL =格式化 tpl + arg
3. 执行SQL语句
end
delimiter \CREATE PROCEDURE p7(
in nid int
)
BEGIN
set @nid = nid; -- 因为 execute 只能使用@ 所以要给他赋值
PREPARE prod FROM ‘select * from student where sid > ?‘;
-- 预检测SQL语句
EXECUTE prod USING @nid;
-- 拼接
DEALLOCATE prepare prod;
END\delimiter ;
对于频繁查找的列要创建索引
select * from tb where 列名="...”
快速查找:
select * from tb where id = 65
从前往后依次查询
以下并非真实索引
覆盖索引:
--在索引文件中直接获取数据
select id from userinfo3 where email = ".....";
索引合并:
--把多个单列索引合并使用
select id from userinfo3 where email = "....." and pd = ”...“;
create index 索引名 on 表名( 列名 );
create unique index 索引名 on 表名( 列名 );
create unique index 索引名 on 表名( 列名1,列名2 );
select * from 表名 where 列名1 = xxx and 列名2 = xxx; -- 走索引
select * from 表名 where 列名2 = xxx; -- 不走索引
-- 联合索引的效率大于索引合并
create index 索引名 on 表名( 列名(16) ) -- 对列名1的16个字节之后的数据建立索引
注意: 在 Mysql 里 TEXT 类型要想建立索引必须建立短索引,否则报错
如 SQLAlchmy
当一类函数公用同样参数时候,可以转变成类进行 - 分类
面向对象: 数据和逻辑(属性和行为)组合在一起
函数编程: 数据和逻辑分离
模板“约束”
提取共性
一类事物共同具有:属性和行为
DB first:
code first:
SQLAlchmy 属于该类
不用like,用 like 永远也命中不了索引
特别的:当or条件中有未建立索引的列才失效,以下会走索引
select * from tb1 where nid = 1 or name = ‘seven‘;
select * from tb1 where nid = 1 or name = ‘seven@live.com‘ and email = ‘alex‘
select * from tb1 where email != ‘...‘
-- 特别的:如果是主键,则还是会走索引
select * from tb1 where nid != 123
select * from tb1 where email > ‘alex‘
-- 特别的:如果是主键或索引是整数类型,则还是会走索引
select * from tb1 where nid > 123
select * from tb1 where num > 123
select name from tb1 order by email desc;( 前后不一致不走索引 )
-- 当根据索引排序时候,选择的映射如果不是索引,则不走索引
-- 特别的:如果对主键排序,则还是走索引:
select * from tb1 order by nid desc;
避免使用select *
count(1)或count(列) 代替 count(*)
创建表时尽量时 char 代替 varchar
表的字段顺序固定长度的字段优先
组合索引代替多个单列索引(经常使用多个条件查询时)
尽量使用短索引
使用连接(JOIN)来代替子查询(Sub-Queries)
-- MYSQL里已经没有区别了
连表时注意条件类型需一致
索引散列值(重复少)不适合建索引,例:性别不适合
因为mysql默认;为语句结束符,所以当执行复合语句内部[begin...end]时会出错,解决如下:
delimiter // 修改语句结束符为 //
create trigger tri_before_insert after insert ON tb1 For EACH ROW
begin
...;
end//
delimiter ; 还原,避免其他语句被干扰
补充:
-- NEW,代指新数据(添加的时候有)
insert into tb() values( NEW.user );
-- OLD,代指老数据( 删除的时候有 )
补充:
NEW,代指新数据(添加的时候有)
insert into tb() values( NEW.user );
OLD,代指老数据( 删除的时候有 )
show variables like ‘%query%‘
set global 变量名 = 值
set global slow_query_log = ON; --开启慢日志,默认关闭
mysqld --defaults-file=‘E:\wupeiqi\mysql-5.7.16-winx64\mysql-5.7.16-winx64\my-default.ini‘
my.conf内容:
slow_query_log = ON
slow_query_log_file = D:/....
原文:https://www.cnblogs.com/dongmll/p/14118487.html