数据库服务器,数据管理系统,数据库,表和记录
装文件的电脑,MySQL软件,文件夹,文件和文件的每一行内容
描述事物的符号记录(特征)称为数据,描述事物的符号既可以是数字,也可以是文字、图片,图像、声音、语言等,数据由多种表现形式,它们都可以经过数字化后存入计算机
数据库即存放数据的仓库,只不过这个仓库是在计算机存储设备上,而且数据是按一定的格式存放的
过去人们将数据存放在文件柜里,现在数据量庞大,已经不再适用
数据库是长期存放在计算机内、有组织、可共享的数据即可。
数据库中的数据按一定的数据模型组织、描述和储存,具有较小的冗余度、较高的数据独立性和易扩展性,并可为各种 用户共享
分两大类:
在了解了Data与DB的概念后,如何科学地组织和存储数据,如何高效获取和维护数据成了关键
这就用到了一个系统软件—数据库管理系统
如MySQL、Oracle、SQLite、Access、MS SQL Server
在官网下载相应版本。
官网链接:https://dev.mysql.com/downloads/mysql
如果想要让MySQL安装在指定目录,那么就将解压后的文件夹移动到指定目录,如:C:\mysql-5.7.16-winx64
MySQL解压后的 bin 目录下有一大堆的可执行文件,执行如下命令初始化数据
cd c:\mysql-5.7.16-winx64\bin
mysqld --initialize-insecure
执行命令从而启动MySQL服务
# 进入可执行文件目录
cd c:\mysql-5.7.16-winx64\bin
# 启动MySQL服务
mysqld
由于初始化时使用的【mysqld –initialize-insecure】命令,其默认未给root账户设置密码
# 进入可执行文件目录
cd c:\mysql-5.7.16-winx64\bin
# 连接MySQL服务器
mysql -u root -p
# 提示请输入密码,直接回车
【右键计算机】–>【属性】–>【高级系统设置】–>【高级】–>【环境变量】–>
【在第二个内容框中找到 变量名为Path 的一行,双击】 –>
【将MySQL的bin目录路径追加到变值值中,用;分割】
当再次启动服务仅需
# 启动MySQL服务,在终端任意目录输入
mysqld
# 连接MySQL服务,在终端任意目录输入:
mysql -u root -p
# 制作MySQL的Windows服务,在终端执行此命令:
"c:\mysql-5.7.16-winx64\bin\mysqld" --install
# 移除MySQL的Windows服务,在终端执行此命令:
"c:\mysql-5.7.16-winx64\bin\mysqld" --remove
注册成服务之后,以后再启动和关闭MySQL服务时,仅需执行如下命令(管理员权限下)
# 启动MySQL服务
net start mysql
# 关闭MySQL服务
net stop mysql
设置密码
mysqladmin -uroot password "123"
# 设置初始密码 由于原密码为空,因此-p可以不用
mysqladmin -uroot -p"123" password "456"
# 修改mysql密码,因为已经有密码了,所以必须输入原密码才能设置新密码
登录命令格式
mysql -h172.31.0.2 -uroot -p456
mysql -uroot -p
mysql 以root用户登录本机,密码为空
方法一:删除授权库mysql,重新初始化
# rm -rf /var/lib/mysql/mysql #所有授权信息全部丢失!!!
# systemctl restart mariadb
# mysql
方法二:启动时跳过授权库,修改密码后重新登录
# vim /etc/my.cnf #mysql主配置文件
[mysqld]
skip-grant-table
# systemctl restart mariadb
# mysql
MariaDB [(none)]> update mysql.user set password=password("123") where user="root" and host="localhost";
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> \q
# #打开/etc/my.cnf去掉skip-grant-table,然后重启
# systemctl restart mariadb
# mysql -u root -p123 #以新密码登录
基本方法,跳过授权表登录
方法一
#1 关闭mysql
#2 在cmd中执行:
mysqld --skip-grant-tables
#3 在cmd中执行:
mysql
#4 执行如下sql:
update mysql.user set authentication_string=password('') where user = 'root';
flush privileges;
#5 tskill mysqld(tskill无法使用时先用tasklist寻找mysqld的PID再用taskkill杀死进程)
#6 重新启动mysql
方法二
#1. 关闭mysql,可以用tskill将其杀死(tskill无法使用时先用tasklist寻找mysqld的PID再用taskkill杀死进程)
#2. 在解压目录下,新建mysql配置文件my.ini
#3. my.ini内容,指定
[mysqld]
skip-grant-tables
#4.启动mysqld
#5.在cmd里直接输入mysql登录,然后操作
update mysql.user set authentication_string=password('') where user='root and host='localhost';
flush privileges;
#6.注释my.ini中的skip-grant-tables,然后重新启动myqsld,然后就可以以新密码登录了
#在mysql的解压目录下,新建my.ini,然后配置
#1. 在执行mysqld命令时,下列配置会生效,即mysql服务启动时生效
[mysqld]
;skip-grant-tables
port=3306
character_set_server=utf8
#解压的目录
basedir=E:\mysql-5.7.19-winx64
#data目录
datadir=E:\my_data #在mysqld --initialize时,就会将初始数据存入此处指定的目录,在初始化之后,启动mysql时,就会去这个目录里找数据
#2. 针对客户端命令的全局配置,当mysql客户端命令执行时,下列配置生效
[client]
port=3306
default-character-set=utf8
user=root
password=123
#3. 只针对mysql这个客户端的配置,2中的是全局配置,而此处的则是只针对mysql这个命令的局部配置
[mysql]
;port=3306
;default-character-set=utf8
user=egon
password=4573
#!!!如果没有[mysql],则用户在执行mysql命令时的配置以[client]为准
mac mysql error You must reset your password using ALTER USER statement before executing this statement.
解决方法
step 1: SET PASSWORD = PASSWORD('your new password');
step 2: ALTER USER 'root'@'localhost' PASSWORD EXPIRE NEVER;
step 3: flush privileges;
在mysql内use数据库时:
在mysql外部:
导入多个数据库
mysqldump -h 源IP -uroot -p –databases db1 | mysql -h -目标IP -u用户名 -p密码
create user 'username'@'允许ip来源' identified by 'password'
grant all privileges on *.* to 'username'@'允许ip来源';
grant all privileges on 数据库名.表名 to 'username'@'允许ip来源';
grant insert,select[,update,delete] on 数据库名.* to 'username'@'允许ip来源';
查看当前用户信息
select user();
create database db1 charset utf8;
SHOW CREATE DATABASE db_name
show databases;
show create database db1;
ALTER {DATABASE | SCHEMA} db_name UPGRADE DATA DIRECTORY NAME
alter database db1 charset gbk;
DROP {DATABASE | SCHEMA} [IF EXISTS] db_name
drop database db1;
切换到文件夹下:
use db1;
简易例子:
create table t1(id int, name char(10)) engine=innodb;
create table t2(id int, name char(10)) engine=innodb;
create table t4 select * from t1 where 1=2;
完整命令:
SHOW CREATE TABLE tbl_name
show tables;
show create table t1;
# 查看表结构
desc/describe t1;
alter table t1 add age int;
alter table t1 modify name char(12);
完整命令
DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] … [RESTRICT | CASCADE]
drop table t2;
insert into db1.t1 values(1,'chuck',19),(2,'chuck2',20),(3,'chuck3',21);
insert into t1 value(4,'chuck4',20);
insert into t1(name) value('chuck5');
select \* from t1;
select name from t1;
select name,id from t1;
update t1 set name='NOBODY' where id=4;
update t1 set name='None' where name=chuck;
update t1 set id=12 where name='None';
Single-table syntax
Multiple-table syntax
delete from t1 where id=4;
delete from t1; # 清空表
truncate # :截断,比delete删除快
truncate t1; # 清空表
create table t1(id int not null, name char(10));
primary key为主键,不为空,且唯一,等同not null unique
create table t4(id int not null unique, name char(10));
auto_increment:自增
create table t5(id int primary key auto_increment, name char(10));
insert into t5(name) values('chuck'),('chuck2'),('chuck3'),('chuck4'),('chuck5');
自增的字段需要用truncate清空表后才可以从1开始自增
表结构和记录
create table t6 select * from t5;
create table t3 like t1;
表结构
create table t7 select * from t5 where 1=2;
alter table t7 modify id int primary key auto_increment;
create table t8 like t5;
# 创建用户
create user 'temp'@'localhost' identified by '123';
# insert delete update select
# 级别1:所有库,所有表,所有字段
grant select on *.* to 'temp'@'localhost' identified by '123';
# 级别2:对db1下的所有表,所有字段
grant select on db1.* to 'temp2'@'localhost' identified by '123';
# 级别3:对db下的t1表的所有字段
grant select on db1.t1 to 'temp3'@'localhost' identified by '123';
# 级别4:对db下的t1表的id字段
grant select (id) on db1.t1 to 'temp4'@'localhost' identified by '123';
# 修改完毕后
flush privileges;
完整命令
整数的length表示显示的长度(在zerofill启用时有效)
create table student(id int,name char(5),born_date date,born_year year,reg_time datetime,class_time time);
mysql> desc student;
+------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | char(5) | YES | | NULL | |
| born_date | date | YES | | NULL | |
| born_year | year(4) | YES | | NULL | |
| reg_time | datetime | YES | | NULL | |
| class_time | time | YES | | NULL | |
+------------+----------+------+-----+---------+-------+
insert into student values(1,'chuck',now(),now(),now(),now());
mysql> select * from student;
+------+-------+------------+-----------+---------------------+------------+
| id | name | born_date | born_year | reg_time | class_time |
+------+-------+------------+-----------+---------------------+------------+
| 1 | chuck | 2017-09-06 | 2017 | 2017-09-06 10:52:12 | 10:52:12 |
+------+-------+------------+-----------+---------------------+------------+
1 row in set (0.00 sec)
create table student(
id int primary key auto_increment,
name char(5),
sex enum('male','female'),
hobbies set('coding','read','music','study')
);
mysql> desc student;
+---------+--------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------------------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | char(5) | YES | | NULL | |
| sex | enum('male','female') | YES | | NULL | |
| hobbies | set('coding','read','music','study') | YES | | NULL | |
+---------+--------------------------------------+------+-----+---------+----------------+
insert into student(name,sex,hobbies) values('chuck','male','coding,read,music');
mysql> select * from student;
+----+-------+------+-------------------+
| id | name | sex | hobbies |
+----+-------+------+-------------------+
| 1 | chuck | male | coding,read,music |
+----+-------+------+-------------------+
ZEROFILL 使用0填充
DEFAULT 为该字段设置默认值
[not null]
create table student2(
id int primary key auto_increment,
name char(5),
sex enum('male','female') not null,
hobbies set('coding','read','music','study')
);
[default]
insert into student2(name,sex,hobbies) values('chuck',null,'coding,read,music');
insert into student2(name,hobbies) values('chuck2','coding,read,music');
create table student3(
id int primary key auto_increment,
name char(5),
age int not null default 18
);
单列唯一
create table teacher(
id int not null unique,
name char(5)
);
多列唯一
create table services(
name char(10),
host char(15),
port int,
unique(host,port)
);
mysql> desc services;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name | char(10) | YES | | NULL | |
| host | char(15) | YES | MUL | NULL | |
| port | int(11) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
mysql> show create table services;
+----------+-----------------------------------------------------------------+
| Table | Create Table |
+----------+-----------------------------------------------------------------+
| services | CREATE TABLE `services` ( |
| | `name` char(10) DEFAULT NULL, |
| | `host` char(15) DEFAULT NULL, |
| | `port` int(11) DEFAULT NULL, |
| | UNIQUE KEY `host` (`host`,`port`) |
| | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+----------+-----------------------------------------------------------------+
insert into services values('ftp','127.0.0.1',8080);
insert into services values('ftp','127.0.0.1',8080);
insert into services values('ftp','127.0.0.1',8081);
create table dep(
id int primary key auto_increment,
name char(10)
);
insert into dep(name) values('IT'),('Boss'),('HR'),('Sale');
select * from dep;
+----+------+
| id | name |
+----+------+
| 1 | IT |
| 2 | Boss |
| 3 | HR |
| 4 | Sale |
+----+------+
show create table dep;
+-------+---------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------+
| dep | CREATE TABLE `dep` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` char(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 |
+-------+---------------------------------------------------------+
# 可以看到AUTO_INCREMENT就是自增的偏移量,可以在建表的时候通过alter修改
create table dep1(
id int primary key auto_increment,
name char(10)
)auto_increment=10;
show create table dep1;
+-------+-------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------+
| dep1 | CREATE TABLE `dep1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` char(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 |
+-------+-------------------------------------------------------+
insert into dep1(name) values('IT'),('Boss'),('HR'),('Sale');
select * from dep1;
+----+------+
| id | name |
+----+------+
| 10 | IT |
| 11 | Boss |
| 12 | HR |
| 13 | Sale |
+----+------+
create table dep2(
id int primary key auto_increment,
name char(10)
);
# 对单次会话修改
# 设置步长
set session auto_increment_increment=2;
# 设置初始偏移量
set session auto_increment_offset=2;
# 全局修改,所有会话都有效
# set global auto_increment_increment=2;
insert into dep(name) values('IT'),('Boss'),('HR'),('Sale');
# mysql 特性:初始偏移量不能比步长小,否则初始偏移量会失效
FOREIGN KEY (FK) 标识该字段为该表的外键
# 表类型必须是innodb存储引擎,且被关联的字段,即references指定的另外一个表的字段,必须保证唯一
# 必须先创建被关联的父表
create table dep(
id int primary key auto_increment,
name varchar(20) not null
)engine=innodb;
# dep_id外键,关联父表(dep主键id),同步更新,同步删除
create table emp(
id int primary key auto_increselment,
name varchar(20) not null,
dpt_id int,
constraint fk_name foreign key(dpt_id) references dep(id)
on delete cascade
on update cascade
)engine=innodb;
# 先往父表dep中插入记录
insert into dep values
(1,'欧德博爱技术有限事业部'),
(2,'艾利克斯人力资源部'),
(3,'销售部');
# 再往子表emp插入记录
insert into emp values
(1,'egon',1),
(2,'alex',2),
(3,'alex2',2),
(4,'alex3',2),
(5,'jack',3),
(6,'jack2',3),
(7,'jack3',3),
(8,'tom',3),
(9,'tom2',3)
;
# 删父表dep,子表emp中对应的记录跟着删
delete from dep where id=2;
select * from emp;
+----+-------+--------+
| id | name | dpt_id |
+----+-------+--------+
| 1 | egon | 1 |
| 5 | jack | 3 |
| 6 | jack2 | 3 |
| 7 | jack3 | 3 |
| 8 | tom | 3 |
| 9 | tom2 | 3 |
+----+-------+--------+
# 更新父表dep,子表emp中对应的记录跟着改
update dep set id=303 where id =3;
select * from emp;
+----+-------+--------+
| id | name | dpt_id |
+----+-------+--------+
| 1 | egon | 1 |
| 5 | jack | 303 |
| 6 | jack2 | 303 |
| 7 | jack3 | 303 |
| 8 | tom | 303 |
| 9 | tom2 | 303 |
+----+-------+--------+
create table author(
id int primary key auto_increment,
name varchar(20)
);
create table book(
id int primary key auto_increment,
name varchar(20)
);
#这张表就存放作者表与书表的关系,即查询二者的关系查这表就可以了
create table author2book(
id int not null unique auto_increment,
author_id int not null,
book_id int not null,
constraint fk_author foreign key(author_id) references author(id)
on delete cascade on update cascade,
constraint fk_book foreign key(book_id) references book(id)
on delete cascade on update cascade,
primary key(author_id,book_id)
);
查询练习:
详细参阅http://www.cnblogs.com/linhaifeng/articles/7274563.html#_label2
import pymysql
# 链接mysql,使用数据库
conn = pymysql.connect(host='localhost', user='root', password='', database='day47', charset='utf8')
# 拿到mysql的游标(可接收输入命令的)
cursor = conn.cursor()
# 编写sql语句
sql = 'select * from user;'
# 拿到受影响的行数
res = cursor.execute(sql)
print('%s rows in set (0.00sec)'%res)
cursor.close()
conn.close()
import pymysql
user = input('username: ').strip()
pwd = input('password: ').strip()
# 链接mysql,使用数据库
conn = pymysql.connect(host='localhost', user='root', password='', database='day47', charset='utf8')
# 拿到mysql的游标(可接收输入命令的)
cursor = conn.cursor()
sql = 'select * from user where name="%s" and pwd="%s";' % (user, pwd)
print(sql)
# 拿到受影响的行数
res = cursor.execute(sql)
# 当查询有结果说明用户名和密码是正确的则登录成功
if res:
print('Login success')
else:
print('Login failure')
cursor.close()
conn.close()
在上面的例子中,按照给定的标准输入用户名和密码可以正常登陆,但是如果非正常输入呢? 对于上面的例子,登录时输入:
username: xxx" or 1=1 #
password:
select * from user where name="xxx" or 1=1 #" and pwd="";
Login success
明显用户名和密码不是正确的但是依然登陆成功,可以复制第三行生成的sql语句在终端里面输入一下,看看是什么情况:
mysql> select * from user where name="xxx" or 1=1 #" and pwd="";
-> ;
+----+-------+------+
| id | name | pwd |
+----+-------+------+
| 1 | egon | 123 |
| 2 | alex | 123 |
| 3 | chuan | 123 |
+----+-------+------+
3 rows in set (0.00 sec)
解决办法就是对用户的输入进行语法检查(但要知道,这并不总是有效的),对于pymysql来说提供了检查服务:
import pymysql
user = input('username: ').strip()
pwd = input('password: ').strip()
# 链接mysql,使用数据库
conn = pymysql.connect(host='localhost', user='root', password='', database='day47')
# 拿到mysql的游标(可接收输入命令的)
cursor = conn.cursor()
sql = 'select * from user where name=%s and pwd=%s;'
# 拿到受影响的行数
res = cursor.execute(sql, (user, pwd))
if res:
print('Login success')
else:
print('Login failure')
cursor.close()
conn.close()
import pymysql
# 链接mysql,使用数据库
# conn = pymysql.connect(host='localhost', user='root', password='', database='day47')
# conn.set_charset('utf8')
conn = pymysql.connect(host='localhost', user='root', password='', database='day47', charset='utf8')
# 拿到mysql的游标(可接收输入命令的)
cursor = conn.cursor()
sql = 'insert into user(name, pwd) values(%s, %s);'
# 拿到受影响的行数
# 插入单条记录
# res = cursor.execute(sql, ('哈大', '123'))
# 插入多条记录
res = cursor.executemany(sql, [('哈大', '123'), ('sada', '123')])
print('%s rows in set (0.00sec)' % res)
# 提交到mysql才算修改了
conn.commit()
cursor.close()
conn.close()
import pymysql
# 链接mysql,使用数据库
conn = pymysql.connect(host='localhost', user='root', password='', database='day47')
conn.set_charset('utf8')
# 拿到mysql的游标(可接收输入命令的)
cursor = conn.cursor()
sql = 'select * from user;'
# 执行sql语句
cursor.execute(sql)
逐条取出
rows = cursor.fetchone()
rows2 = cursor.fetchone()
rows3 = cursor.fetchone()
print(rows)
print(rows2)
print(rows3)
多条取出
print(cursor.fetchmany(3))
print(cursor.fetchone())
全部取出
print(cursor.fetchall())
print(cursor.fetchone())
光标移动-绝对位置
print(cursor.fetchall())
cursor.scroll(2, mode='absolute') # 绝对位置,以文件开头为目标,数字表示移动次数
print(cursor.fetchall())
光标移动相对位位置
print(cursor.fetchone())
print(cursor.fetchone())
cursor.scroll(-1, mode='relative') # 相对位置,以当前光标为目标,数字表示移动次数
print(cursor.fetchall())
cursor.close()
conn.close()
在MySQL内查看所有配置信息
LAMP
Apache MySQL PHP Linux
LNMP Nginx MySQL PHP/Python Linux
MySQL –> MariaDB