在开发中有很多设计数据库的软件,常用的如power designer,db desinger等,这些软件可以直观的看到实体及实体间的关系
目录
- 1. SQL分类
- 2. MySQL安装(查看另一帖,安装版本8.0)
- 3. 数据完整性
- 4. 命令
- 5. 查询
- 6. Python操作MySQL
- 7. 高级主题
- 8 主从配置
- 9. MySQL命名规范
1. SQL分类
SQL语言主要分为:
分类 | 解释 |
---|---|
DQL | 数据查询语言,用于对数据进行查询,如select |
DML | 数据操作语言,对数据进行增加、修改、删除,如insert、udpate、delete |
TPL | 事务处理语言,对事务进行处理,包括begin transaction、commit、rollback |
DCL | 数据控制语言,进行授权与权限回收,如grant、revoke |
DDL | 数据定义语言,进行数据库、表的管理等,如create、drop |
CCL | 指针控制语言,通过控制指针完成表的操作,如declare cursor |
SQL不区分大小写
2. MySQL安装(查看另一帖,安装版本8.0)
安装客户端:
sudo apt-get install mysql-client
安装完SQL5.7之后没有设置root
的密码,运行:
sudo mysql_secure_installation
2.1 Ubuntu18安装mysql 8
第一步: 添加MySQL APT Repository
1. 前往下载页面下载MySQL APT repository
https://dev.mysql.com/downloads/repo/apt/
2. 使用如下命令安装配置
包名换成刚才下载的.deb
名称
shell> sudo dpkg -i /PATH/version-specific-package-name.deb
安装期间会被提示选择MySQL server的版本和其他组件,如果不确定的话就选择默认即可
3. 更新
shell> sudo apt-get update
第二步 使用apt-get 安装mysql
shell> sudo apt-get install mysql-server
安装过程中会提示设置root用户密码,记住这个密码
第三步 开启/关闭mysql服务
shell> sudo service mysql status
shell> sudo service mysql start
shell> sudo service mysql stop
2.2 移除mysql
推荐:
sudo apt-get remove --purge mysql-server
或者:
# 先移除mysql server
shell> sudo apt-get remove mysql-server
# 再移除其他安装的包
shell> sudo apt-get autoremove
# 移除mysql apt repository
shell> sudo apt-get remove mysql-apt-config
# 检查是否完全删除
shell> dpkg -l | grep mysql | grep ii
按照上面的删除方法,并没有删除全部的依赖和配置文件,解决办法:
tar -zcvf ~/msql_backup.tar.gz /etc/mysql /var/lib/mysql
sudo apt purge mysql-server mysql-client mysql-common mysql-server-core mysql-client-core
sudo rm -rfv /etc/mysql /var/lib/mysql
sudo apt autoremove
sudo apt autoclean
参考链接: https://askubuntu.com/questions/763534/cannot-reinstall-mysql-server-after-its-purge
3. 数据完整性
3.1 数据类型
常用数据类型如下:
- 整数:int,bit
- 小数:decimal : 如
decimal(5,2)
代表数字有共有5个,小数位2个 - 字符串:varchar,char
- 大文本: text
- 日期时间: date, time, datetime
- 枚举类型(enum)
对于图片、音频、视频等文件,不存储在数据库中,而是上传到某个服务器上,然后在表中存储这个文件的保存路径
数值类型:
类型 | 字节大小 | 有符号范围(Signed) | 无符号范围(Unsigned) |
---|---|---|---|
TINYINT | 1 | -128 ~ 127 | 0 ~ 255 |
SMALLINT | 2 | -32768 ~ 32767 | 0 ~ 65535 |
MEDIUMINT | 3 | -8388608 ~ 8388607 | 0 ~ 16777215 |
INT/INTEGER | 4 | -2147483648 ~2147483647 | 0 ~ 4294967295 |
BIGINT | 8 | -9223372036854775808 ~ 9223372036854775807 | 0 ~ 18446744073709551615 |
字符串:
类型 | 字节大小 | 示例 |
---|---|---|
CHAR | 0-255 | 类型:char(3) 输入 ‘ab’, 实际存储为’ab ‘, 输入’abcd’ 实际存储为 ‘abc’ |
VARCHAR | 0-255 | 类型:varchar(3) 输 ‘ab’,实际存储为’ab’, 输入’abcd’,实际存储为’abc’ |
TEXT | 0-65535 | 大文本 |
日期时间类型:
类型 | 字节大小 | 示例 |
---|---|---|
DATE | 4 | ‘2020-01-01’ |
TIME | 3 | ‘12:29:59’ |
DATETIME | 8 | ‘2020-01-01 12:29:59’ |
YEAR | 1 | ‘2017’ |
TIMESTAMP | 4 | ‘1970-01-01 00:00:01’ UTC ~ ‘2038-01-01 00:00:01’ UTC |
3.2 约束
- 主键
primary key
:物理上存储的顺序 - 非空
not null
:此字段不允许填写空值 - 惟一
unique
:此字段的值不允许重复 - 默认
default
:当不填写此值时会使用默认值,如果填写时以填写为准 - 外键
foreign key
:对关系字段进行约束,当为关系字段填写值时,会到关联的表中查询此值是否存在,如果存在则填写成功,如果不存在则填写失败并抛出异常
说明:虽然外键约束可以保证数据的有效性,但是在进行数据的crud(增加、修改、删除、查询)时,都会降低数据库的性能,所以不推荐使用,那么数据的有效性怎么保证呢?答:可以在逻辑层进行控制
4. 命令
命令 | 说明 |
---|---|
mysql --help |
查看所有命令和帮助 |
mysql -u用户名 -p |
连接数据库(本地) |
mysql -h host -u user -p |
连接数据库 |
exit| quit | ctrl+d |
退出mysql交互环境 |
SHOW DATABASES |
显示自己有权限查看的数据库 |
SELECT CURRENT_DATE; |
显示当前日期 |
SELECT NOW(); |
显示当前时间 |
SELECT VERSION(); |
显示当前版本 |
USE 数据库名 |
使用数据库 |
4.1 基本数据库操作
a. 创建数据库
CREATE DATABASE 数据库名称 CHARSET=UTF8; --注意这里没有 -
b. 查看创建数据库语句
SHOW CREATE DATABASE 数据库名称;
c. 删除数据库
DROP DATABASE 数据库名称;
-- 如果数据库名称中有特殊符号,就加上 ``
DROP DATABASE `PYTHON-04`;
d. 切换数据库
USE 数据库名;
e. 查看当前数据库
SELECT DATABASE();
f. 备份数据库
mysqldump –uroot –p 数据库名 > python.sql;
# 按提示输入mysql的密码
g. 从备份恢复
要先创建数据库,再运行sql语句
mysql -uroot –p 新数据库名 < python.sql
# 根据提示输入mysql密码
4.2 基本表操作
a. 查看数据库中的表
SHOW TABLES;
b. 创建表
CREATE TABLE 表名(
字段名 类型 [约束],
字段名 类型 [约束],
...
);
CREATE TABLE MAIN(
ID INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(255)
)
CREATE TABLE MAIN(
ID INT UNSIGNED, -- 还能指定有没有符号
NAME VARCHAR(255)
)
-- 一个完整的表
CREATE TABLE STUDENTS(
ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(30);
AGE TINYINT UNSIGNED DEFAULT 0;
HIGH DECIMAL(5,2);
GENDER ENUM("男","女","中性","保密") DEFAULT "保密",
CLS_ID INT UNSIGNED;
)
-- 约束写最后:
CREATE TABLE table_name(
column1 datatype contrai,
column2 datatype,
column3 datatype,
.....
columnN datatype,
PRIMARY KEY(one or more columns)
);
c. 查看表结构
DESC 表名;
d. 更改表名
rename table 原表名 to 新表名;
e. 添加字段
ALTER TABLE 表名 ADD 列名 类型;
f. 重命名字段
alter table 表名 change 原名 新名 类型及约束;
g. 修改字段
ALTER TABLE 表名 MODIFY 列名 类型及约束;
h. 删除字段
ALTER TABLE 表名 DROP 列名;
i. 删除表
DROP TABLE 表名;
j. 查看表的创建语句
SHOW CREATE TABLE 表名;
InnoDB引擎比 MyISAM最主要的区别是 支持事务处理、外键、行级锁
4.3 CURD
a. 插入
-- 全部插入
INSERT INTO 表名 VALUES(值,值...);
-- 部分插入
INSERT INTO 表名(列, 列) VALUES(值,值);
-- 多行插入
INSERT INTO 表名(列, 列) VALUES(值,值),(值,值),(值,值).. ;
- 主键自增位置可以使用
0
,null
,default
来默认设置 - 枚举字段可以插入对应字符串,也可以插入数字,从1开始
- 对于有默认值的字段,可以写
default
来插入
b. 修改
UPDATE 表名 SET 列=值, 列=值... WHERE 条件;
c. 删除
DELETE FROM 表名 WHERE 条件;
d. 查询
SELECT * FROM 表名 WHERE 条件;
SELECT 列名 [AS 别名], 列名 [AS 别名], 列名 [AS 别名] FROM 表名;
5. 查询
5.1 查询——条件
select * from 表名 where 条件;
where后面支持多种运算符,进行条件的处理:
- 比较运算符
- 逻辑运算符
- 模糊查询
- 范围查询
- 空判断
a. 比较运算符
= < <= > >= != 或者 <>
b. 逻辑运算符
and or not
c. 模糊查询
like
%
表示任意字符,0个—多个_
表示任意一个
select * from students where name like '黄%'; --黄开头的任何
select * from students where name like '黄_'; -- 黄开头并且是2个字
d. 范围查询
in
between and
select * from students where id in(1,3,8);
select * from students where id between 3 and 8;
e. 空判断
is null
is not null
5.2 查询——排序
select * from 表名 order by 列1 asc|desc [,列2 asc|desc,...]
5.3 查询——聚合
sum
count
min
max
avg
SELECT SUM(AGE)/COUNT(*) FROM STUDENT; --可以做计算
SELECT ROUND(SUM(AGE)/COUNT(*),2) FROM STUDENT; --ROUND函数可以指定保留小数
在数据库中存储小数点,总是容易出误差,解决办法是 将结果存储100、1000等变成整数
5.4 查询——分组
SELECT ... FROM ... GROUP BY 列名.
查看组内有哪些内容:group_concat
SELECT COUNT(*), GROUP_CONCAT(NAME) FROM STUDENT;
SELECT COUNT(*), GROUP_CONCAT(NAME,ID) FROM STUDENT;
SELECT COUNT(*), GROUP_CONCAT(NAME,"分隔符",ID) FROM STUDENT;
分组后筛选:
SELECT GENDER FROM STUDENT GROUP BY GENDER HAVING AVG(AGE)>30;
where 是对表内容进行过滤,而having是对groupby之后的临时结果集进行过滤
with rollup:
with rollup
的作用是在最后新增一行,来记录当前列里所有记录的总和
select gender,count(*) from students group by gender with rollup;
+--------+----------+
| gender | count(*) |
+--------+----------+
| 男 | 5 |
| 女 | 7 |
| 中性 | 1 |
| 保密 | 1 |
| NULL | 14 |
+--------+----------+
5.5 查询——分页
LIMIT start count
SELECT * FROM STUDENT LIMIT 5; -- 限制个数
SELECT * FROM STUDENT LIMIT 0,5; -- 从第几个开始,限制几个(第一条记录的索引为0)
5.6 查询——连接
MYSQl中的连接:
left join/left outer join
right join/right outer join
inner join/join
- 笛卡尔积
select * from 表1 inner或left或right join 表2 on 表1.列 = 表2.列
连接之后可以筛选,dongge的意思是,只有在对原表筛选的时候使用where
,而其他的临时结果进行筛选都用having
:
select * from students inner join classes on students.cls_id = classes.id having student.age>18;
5.7 自连接
select city.* from areas as city
inner join areas as province on city.pid=province.aid
where province.atitle='山西省';
5.8 子查询
在一个 select 语句中,嵌入了另外一个 select 语句, 那么被嵌入的 select 语句称之为子查询语句
- 子查询是辅助主查询的,要么充当条件,要么充当数据源
子查询分类
- 标量子查询: 子查询返回的结果是一个数据(一行一列)
select * from students where age > (select avg(age) from students);
- 列子查询: 返回的结果是一列(一列多行)
select name from classes where id in (select cls_id from students);
- 行子查询: 返回的结果是一行(一行多列)
select * from students where (height,age) = (select max(height),max(age) from students);
- 表级子查询: 返回的是一个多行多列表—— 可以将这个结果用来和其他的join
select * from goods
inner join
(
select
cate_name,
max(price) as max_price,
min(price) as min_price,
avg(price) as avg_price,
count(*) from goods group by cate_name
) as goods_new_info
on goods.cate_name=goods_new_info.cate_name and goods.price=goods_new_info.max_price;
5.9 完整SQL语句结构
SELECT select_expr [,select_expr,...] [
FROM tb_name
[WHERE 条件判断]
[GROUP BY {col_name | postion} [ASC | DESC], ...]
[HAVING WHERE 条件判断]
[ORDER BY {col_name|expr|postion} [ASC | DESC], ...]
[ LIMIT {[offset,]rowcount | row_count OFFSET offset}]
]
执行顺序为:
- from 表名
- where …
- group by …
- select distinct *
- having …
- order by …
- limit start,count
6. Python操作MySQL
6.0 准备步骤
修改mysql配置文件
- /etc/mysql/mysql/cnf # 总配置,里面引入了下面2个配置
- /etc/mysql/mysql.conf.d/mysqld.cnf # 这是 mysql-server的配置
- /etc/mysql/conf.d/mysql.cnf # 这是 mysql-client的配置
在/etc/mysql/mysql.conf.d/mysqld.cnf
中设置 bind-address = 0.0.0.0
或者 不设置这一句,代表允许localhost
以外的IP连接
配置virtualbox的端口映射
上面配置了端口转发,意思就是 访问物理主机上的3306端口,就会转发给这个虚拟机的3306端口。
6.1 准备数据和拆分表
-- 创建 "京东" 数据库
create database jing_dong charset=utf8;
-- 使用 "京东" 数据库
use jing_dong;
-- 创建一个商品goods数据表
create table goods(
id int unsigned primary key auto_increment not null,
name varchar(150) not null,
cate_name varchar(40) not null,
brand_name varchar(40) not null,
price decimal(10,3) not null default 0,
is_show bit not null default 1,
is_saleoff bit not null default 0
);
-- 向goods表中插入数据
insert into goods values(0,'r510vc 15.6英寸笔记本','笔记本','华硕','3399',default,default);
insert into goods values(0,'y400n 14.0英寸笔记本电脑','笔记本','联想','4999',default,default);
insert into goods values(0,'g150th 15.6英寸游戏本','游戏本','雷神','8499',default,default);
insert into goods values(0,'x550cc 15.6英寸笔记本','笔记本','华硕','2799',default,default);
insert into goods values(0,'x240 超极本','超级本','联想','4880',default,default);
insert into goods values(0,'u330p 13.3英寸超极本','超级本','联想','4299',default,default);
insert into goods values(0,'svp13226scb 触控超极本','超级本','索尼','7999',default,default);
insert into goods values(0,'ipad mini 7.9英寸平板电脑','平板电脑','苹果','1998',default,default);
insert into goods values(0,'ipad air 9.7英寸平板电脑','平板电脑','苹果','3388',default,default);
insert into goods values(0,'ipad mini 配备 retina 显示屏','平板电脑','苹果','2788',default,default);
insert into goods values(0,'ideacentre c340 20英寸一体电脑 ','台式机','联想','3499',default,default);
insert into goods values(0,'vostro 3800-r1206 台式电脑','台式机','戴尔','2899',default,default);
insert into goods values(0,'imac me086ch/a 21.5英寸一体电脑','台式机','苹果','9188',default,default);
insert into goods values(0,'at7-7414lp 台式电脑 linux )','台式机','宏碁','3699',default,default);
insert into goods values(0,'z220sff f4f06pa工作站','服务器/工作站','惠普','4288',default,default);
insert into goods values(0,'poweredge ii服务器','服务器/工作站','戴尔','5388',default,default);
insert into goods values(0,'mac pro专业级台式电脑','服务器/工作站','苹果','28888',default,default);
insert into goods values(0,'hmz-t3w 头戴显示设备','笔记本配件','索尼','6999',default,default);
insert into goods values(0,'商务双肩背包','笔记本配件','索尼','99',default,default);
insert into goods values(0,'x3250 m4机架式服务器','服务器/工作站','ibm','6888',default,default);
insert into goods values(0,'商务双肩背包','笔记本配件','索尼','99',default,default);
直接从选择结果插入到表:
insert into goods_cates (name) select cate_name from goods group by cate_name;
联合表更新:
update goods as g inner join goods_cates as c on g.cate_name=c.name set g.cate_name=c.id;
直接创建的时候插入值
-- 在创建数据表的时候一起插入数据
-- 注意: 需要对brand_name 用as起别名,否则name字段就没有值
create table goods_brands (
id int unsigned primary key auto_increment,
name varchar(40) not null) select brand_name as name from goods group by brand_name;
同时更改多个列
alter table goods
change cate_name cate_id int unsigned not null,
change brand_name brand_id int unsigned not null;
添加外键
foreign key,只有 innodb数据库引擎 支持外键约束
-- 修改已存在的表
alter table goods add foreign key (brand_id) references goods_brands(id);
-- 创建表时添加
create table goods(
id int primary key auto_increment not null,
name varchar(40) default '',
price decimal(5,2),
cate_id int unsigned,
brand_id int unsigned,
is_show bit default 1,
is_saleoff bit default 0,
foreign key(cate_id) references goods_cates(id),
foreign key(brand_id) references goods_brands(id)
);
----删除外键
-- 需要先获取外键约束名称,该名称系统会自动生成,可以通过查看表创建语句来获取名称
show create table goods;
-- 获取名称之后就可以根据名称来删除外键约束
alter table goods drop foreign key 外键名称;
在实际开发中,很少会使用到外键约束,会极大的降低表更新的效率
6.2 Python操作数据库
a. 创建连接
import pymysql
conn = pymysql.connect(参数列表)
...
conn.close()
# 例子
如果不能联网,下载
whl
文件,然后pip install xxxx.whl
来安装
connect方法参数 | 含义 |
---|---|
host | 连接的mysql主机,如果本机是’localhost’ |
port | 连接的mysql主机的端口,默认是3306 |
database | 数据库的名称 |
user | 连接的用户名 |
password | 连接的密码 |
charset | 通信采用的编码方式,推荐使用utf8 |
connect对象的方法 | 含义 |
---|---|
close |
关闭连接 |
commit |
提交,增删改的时候需要 |
rollback |
回滚,增删改的时候需要 |
cursor |
创建cursor,用于执行SQL语句 |
b. 创建cursor
cur = conn.cursor()
cursor对象的方法 | 含义 |
---|---|
close |
关闭连接 |
execute |
执行SQL语句,返回的是受影响的行数 |
fetchone |
依次返回下一条记录,记录是一个元祖 |
fetchmany |
获取结果集中指定数量的记录,每条记录组成一个元祖,整个结果组成一个大元祖 |
fetchall |
获取结果集所有记录,每条记录组成一个元祖, 整个结果集是一个大的元祖 |
cursor对象的属性 | 含义 |
---|---|
rowcount |
获取最近依次execute 方法受影响的行数 |
connection |
获取当前连接对象 |
c. 增删改
Python执行代码默认是开启了事务的
from pymysql import *
def main():
# 创建Connection连接
conn = connect(host='localhost',port=3306,database='jing_dong',user='root',password='mysql',charset='utf8')
# 获得Cursor对象
cs1 = conn.cursor()
# 执行insert语句,并返回受影响的行数:添加一条数据
# 增加
count = cs1.execute('insert into goods_cates(name) values("硬盘")')
#打印受影响的行数
print(count)
count = cs1.execute('insert into goods_cates(name) values("光盘")')
print(count)
# # 更新
# count = cs1.execute('update goods_cates set name="机械硬盘" where name="硬盘"')
# # 删除
# count = cs1.execute('delete from goods_cates where id=6')
# 提交之前的操作,如果之前已经之执行过多次的execute,那么就都进行提交
conn.commit()
# 关闭Cursor对象
cs1.close()
# 关闭Connection对象
conn.close()
if __name__ == '__main__':
main()
添加了记录之后,就算没有提交,或者就算之后rollback了,那么主键自增也不会回去了。
d. 查询
count = cs1.execute('select id,name from goods where id>=4')
for i in range(count):
# 获取查询的结果
result = cs1.fetchone()
# 打印查询的结果
print(result)
# 获取查询的结果
# 或者
cs1.fetchmany(5)
cs1.fetchall()
e. 防止SQL注入
将参数作为execute
之后的参数传入,而不是自己拼接字符串
params = [find_name]
# 执行select语句,并返回受影响的行数:查询所有数据
count = cs1.execute('select * from goods where name=%s', params)
7. 高级主题
7.1 视图
视图是一张虚表,存储的是查询的规则。
优点:
- 方便操作,减少SQL语句的书写
- 方便控制权限
- 当数据库重构时,可以对程序隐藏底层结构
定义视图
CREATE VIEW 名称 AS
SELECT语句;
查看视图
SHOW TABLES; -- 视图看起来就像一张表
删除视图
DROP VIEW 名称;
7.2 事务
四大特性
- 原子性(Atomicity)
- 一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性
- 一致性(Consistency)
- 数据库总是从一个一致性的状态转换到另一个一致性的状态。
- 隔离性(Isolation)
- 通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的。
- 持久性(Durability)
- 一旦事务提交,则其所做的修改会永久保存到数据库。
只有innobdb引擎才有事务
开启、提交、回滚
- 开启:
begin;
或者start transaction;
- 提交:
commit;
- 回滚:
rollback;
begin;
--CURD操作...;
commit;
事务中增加了数据,就算回滚, auto_increment也还是会增加
参考书:高性能MySQL
7.3 索引
索引是随着表而来的。 主键和外键自动会生成索引。
查看索引
SHOW INDEX FROM 表;
创建索引
CREATE INDEX 索引名称 ON 表名(字段名称(长度));
-- 例子
CREATE INDEX index_name on STUDENT(name(10)); -- 如果name是 varchar(10)
CREATE INDEX index_age on STUDENT(age ); -- int类型不需要加长度
删除索引
DROP INDEX 索引名 ON 表名;
查看语句运行时间
SET profiling=1; -- 开启时间监测
...各种语句
SHOW profiles; -- 查看语句运行时间
7.4 账户管理
MySQL的账户可以分为以下几种
- 服务实例级账号:,启动了一个mysqld,即为一个数据库实例;如果某用户如root,拥有服务实例级分配的权限,那么该账号就可以删除所有的数据库、连同这些库中的表
- 数据库级别账号:对特定数据库执行增删改查的所有操作
- 数据表级别账号:对特定表执行增删改查等所有操作
- 字段级别的权限:对某些表的特定字段进行操作
- 存储程序级别的账号:对存储程序进行增删改查的操作
账户的操作主要包括:
- 创建账户
- 删除账户
- 修改密码
- 授权权限等
用户信息存储位置
mysql中有个数据库叫做mysql,里面的user表就是存储的用户信息:
select host,user,authentication_string from user;
-- host: 用户允许访问的主机
-- user:用户名
-- authentication_string: 加密后的密码
创建新用户,同时设置密码和权限
常用权限包括:create、alter、drop、insert、update、delete、select、all privileges
grant 权限列表 on 数据库 to '用户名'@'访问主机' identified by '密码';
--例子:
GRANT ALL PRIVILEGES ON itcast.* TO 'yyfyifan'@'localhost' IDENTIFIED BY 'password';
查看用户权限
SHOW GRANTS FOR '用户名'@'主机地址';
给与权限
grant 权限名称 on 数据库 to 账户@主机 with grant option;
WITH GRANT OPTION
的意思是,被赋予的权限,可以由该用户继续赋予别人。
修改密码
-- 这一种是直接修改 user表的方式
update user set authentication_string=password('新密码') where user='用户名';
-- 要记得刷新权限
flush privileges
删除用户
DROP USER '用户名'@'主机';
--第二种,直接修改user表
DELETE from user where user='用户名';
flush privileges
连接不上mysql可能的原因
- 网络不通
- 通过 ping xxx.xxx.xx.xxx可以发现网络是否正常
- 查看数据库是否配置了bind_address参数
- 本地登录数据库查看my.cnf文件和数据库当前参数show variables like ‘bind_address’;
- 如果设置了bind_address=127.0.0.1 那么只能本地登录
- 查看数据库是否设置了skip_networking参数
- 如果设置了该参数,那么只能本地登录mysql数据库
- 端口指定是否正确
- 无
忘记root密码怎么办
http://blog.csdn.net/lxpbs8851/article/details/10895085
- 不要设置 主机为%,虽然自己使用方便,但是敌人也可以通过尝试root账户的密码来攻击
- 对用户设置的时候,经常可以不设置 删除出权限,以防删库跑路
8 主从配置
好处:
- 自动数据备份
- 读写分离——往主写,从各处读
- 负载均衡
Mysql服务器之间的主从同步是基于二进制日志机制,主服务器使用二进制日志来记录数据库的变动情况,从服务器通过读取和执行该日志文件来保持和主服务器的数据一致。
在使用二进制日志时,主服务器的所有操作都会被记录下来,然后从服务器会接收到该日志的一个副本。从服务器可以指定执行该日志中的哪一类事件(譬如只插入数据或者只更新数据),默认会执行日志中的所有语句。
每一个从服务器会记录关于二进制日志的信息:文件名和已经处理过的语句,这样意味着不同的从服务器可以分别执行同一个二进制日志的不同部分,并且从服务器可以随时连接或者中断和服务器的连接。
主服务器和每一个从服务器都必须配置一个唯一的ID号(在my.cnf文件的[mysqld]模块下有一个server-id配置项),另外,每一个从服务器还需要通过CHANGE MASTER TO语句来配置它要连接的主服务器的ip地址,日志文件名称和该日志里面的位置(这些信息存储在主服务器的数据库里)
8.1 配置基本步骤
有很多种配置主从同步的方法,可以总结为如下的步骤:
- 在主服务器上,必须开启二进制日志机制和配置一个独立的ID
- 在每一个从服务器上,配置一个唯一的ID,创建一个用来专门复制主服务器数据的账号
- 在开始复制进程前,在主服务器上记录二进制文件的位置信息
- 如果在开始复制之前,数据库中已经有数据,就必须先创建一个数据快照(可以使用mysqldump导出数据库,或者直接复制数据文件)
- 配置从服务器要连接的主服务器的IP地址和登陆授权,二进制日志文件名和位置
8.2 详细步骤
第一步:备份主服务器上数据到从服务器
因为从服务器同步主服务器,是依据主服务器上的日志文件来同步,而不是读取已有数据,这就需要先确保数据已经保存在从服务器上
主服务器上执行:
mysqldump -uroot -pmysql --all-databases --lock-all-tables > ~/master_db.sql
-u :用户名
-p :示密码
--all-databases :导出所有数据库
--lock-all-tables :执行操作时锁住所有表,防止操作时有数据修改
~/master_db.sql :导出的备份数据(sql文件)位置,可自己指定
从服务器上还原
mysql –uroot –pmysql < master_db.sql
第二步:设置主服务器 的id和配置文件地址
打开配置文件:
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
设置 server-id 和 log_bin:
重启服务
sudo service mysql restart
第三步 主服务器创建一个账户,用于从服务器同步
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' identified by 'slave';
FLUSH PRIVILEGES;
第四步 查看主服务器的 主服务信息
SHOW MASTER STATUS;
第五步 配置从服务器信息
- 修改配置文件中 server-id, 和 主服务器的不能相同
- 注释掉 log_bin 这一句
- 然后重启服务
第六步 配置从服务器连接主服务器
登录从服务器,执行:
change master to master_host='10.211.55.5', master_user='slave', master_password='slave',master_log_file='mysql-bin.000006', master_log_pos=590;
master_host:主服务器Ubuntu的ip地址
master_log_file: 前面查询到的主服务器日志文件名
master_log_pos: 前面查询到的主服务器日志文件位置
第七步 查看同步状态
从服务器中,运行
mysql > start slave;
mysql > show slave status \G;
9. MySQL命名规范
9.1 约定
- 如无特殊需求,所有表使用innodb引擎
- 如无特殊需求,所有主键均为自增类型
- 如无特殊需求,所有字段均为NOT NULL,并给定默认值
- 所有字段均设置备注,枚举字段需要说明每个枚举值的意义
- 在能满足取值范围的情况下,选择占用存储空间最小的数据类型。如布尔值使用tinyint,时间类型使用timestamp
9.2 命名规范
-
数据库名:与系统名相同
-
表名:系统名称缩写+_+表名。表名必须描述该表的用途,由单个或多个名词组成,首字母小写,后续单词首字母大写。
-
字段名:字段名必须描述该字段的用途,由单个或多个名词组成,首字母小写,后续单词首字母大写。这里跟其他地方的规范不太一样。阿里规范中要求必须使用下划线的格式,主要考虑某些环境mysql不区分大小写,有些环境区分大小写。其实只要查询时区分大小写就没有问题了,但如果使用下划线的命名方式,在字段映射的时候会非常麻烦。
-
主键字段:表名+Id
-
外键字段:与主表主键字段完全一样
-
主键:
pk
_+表名 -
外键:
fk
+从表名++主表名 -
视图:
view
_+名名称 -
存储过程:
prcd
_+名称 -
函数:
fun
_+名称 -
触发器:
trg
_+名称 -
索引:
idx
_+名称